blob: 1caff13c9c0a083a86362c9e594d2cfe68db451d [file] [log] [blame]
yangsu@google.comdb03eaa2011-08-08 15:37:23 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
epoger@google.com6a121782012-09-14 18:42:01 +00007#include "TransitionView.h"
8
tfarina@chromium.orgb1b7f7072012-09-18 01:52:20 +00009#include "OverView.h"
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000010#include "SampleCode.h"
11#include "SkView.h"
12#include "SkCanvas.h"
13#include "SkTime.h"
14#include "SkInterpolator.h"
15
16static const char gIsTransitionQuery[] = "is-transition";
17static const char gReplaceTransitionEvt[] = "replace-transition-view";
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000018
tfarina@chromium.orgb1b7f7072012-09-18 01:52:20 +000019bool is_transition(SkView* view) {
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000020 SkEvent isTransition(gIsTransitionQuery);
21 return view->doQuery(&isTransition);
22}
23
24class TransitionView : public SampleView {
reed@google.com8d884752012-09-08 20:14:23 +000025 enum {
tfarina@chromium.orgb1b7f7072012-09-18 01:52:20 +000026 // kDurationMS = 500
reed@google.com8d884752012-09-08 20:14:23 +000027 kDurationMS = 1
28 };
tfarina@chromium.orgb1b7f7072012-09-18 01:52:20 +000029
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000030public:
31 TransitionView(SkView* prev, SkView* next, int direction) : fInterp(4, 2){
32 fAnimationDirection = (Direction)(1 << (direction % 8));
rmistry@google.comae933ce2012-08-23 18:19:56 +000033
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000034 fPrev = prev;
35 fPrev->setClipToBounds(false);
36 fPrev->setVisibleP(true);
scroggo@google.comb073d922012-06-08 15:35:03 +000037 (void)SampleView::SetUsePipe(fPrev, SkOSMenu::kOffState);
rmistry@google.comae933ce2012-08-23 18:19:56 +000038 //Not calling unref because fPrev is assumed to have been created, so
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000039 //this will result in a transfer of ownership
40 this->attachChildToBack(fPrev);
rmistry@google.comae933ce2012-08-23 18:19:56 +000041
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000042 fNext = next;
43 fNext->setClipToBounds(true);
44 fNext->setVisibleP(true);
scroggo@google.comb073d922012-06-08 15:35:03 +000045 (void)SampleView::SetUsePipe(fNext, SkOSMenu::kOffState);
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000046 //Calling unref because next is a newly created view and TransitionView
47 //is now the sole owner of fNext
48 this->attachChildToFront(fNext)->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +000049
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000050 fDone = false;
51 //SkDebugf("--created transition\n");
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000052 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000053
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000054 ~TransitionView(){
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000055 //SkDebugf("--deleted transition\n");
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000056 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000057
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000058 virtual void requestMenu(SkOSMenu* menu) {
59 if (SampleView::IsSampleView(fNext))
60 ((SampleView*)fNext)->requestMenu(menu);
61 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000062
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000063protected:
64 virtual bool onQuery(SkEvent* evt) {
65 if (SampleCode::TitleQ(*evt)) {
66 SkString title;
67 if (SampleCode::RequestTitle(fNext, &title)) {
68 SampleCode::TitleR(evt, title.c_str());
69 return true;
70 }
71 return false;
72 }
73 if (evt->isType(gIsTransitionQuery)) {
74 return true;
75 }
76 return this->INHERITED::onQuery(evt);
77 }
78 virtual bool onEvent(const SkEvent& evt) {
79 if (evt.isType(gReplaceTransitionEvt)) {
80 fPrev->detachFromParent();
81 fPrev = (SkView*)SkEventSink::FindSink(evt.getFast32());
scroggo@google.comb073d922012-06-08 15:35:03 +000082 (void)SampleView::SetUsePipe(fPrev, SkOSMenu::kOffState);
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000083 //attach the new fPrev and call unref to balance the ref in onDraw
84 this->attachChildToBack(fPrev)->unref();
85 this->inval(NULL);
86 return true;
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000087 }
88 if (evt.isType("transition-done")) {
89 fNext->setLoc(0, 0);
90 fNext->setClipToBounds(false);
rmistry@google.comae933ce2012-08-23 18:19:56 +000091 SkEvent* evt = new SkEvent(gReplaceTransitionEvt,
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000092 this->getParent()->getSinkID());
93 evt->setFast32(fNext->getSinkID());
94 //increate ref count of fNext so it survives detachAllChildren
95 fNext->ref();
96 this->detachAllChildren();
97 evt->post();
98 return true;
99 }
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000100 return this->INHERITED::onEvent(evt);
101 }
102 virtual void onDrawBackground(SkCanvas* canvas) {}
103 virtual void onDrawContent(SkCanvas* canvas) {
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000104 if (fDone)
105 return;
106
107 if (is_overview(fNext) || is_overview(fPrev)) {
scroggo@google.comb073d922012-06-08 15:35:03 +0000108 fPipeState = SkOSMenu::kOffState;
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000109 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000110
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000111 SkScalar values[4];
112 SkInterpolator::Result result = fInterp.timeToValues(SkTime::GetMSecs(), values);
113 //SkDebugf("transition %x %d pipe:%d\n", this, result, fUsePipe);
114 //SkDebugf("%f %f %f %f %d\n", values[0], values[1], values[2], values[3], result);
115 if (SkInterpolator::kNormal_Result == result) {
116 fPrev->setLocX(values[kPrevX]);
117 fPrev->setLocY(values[kPrevY]);
118 fNext->setLocX(values[kNextX]);
119 fNext->setLocY(values[kNextY]);
120 this->inval(NULL);
121 }
122 else {
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000123 (new SkEvent("transition-done", this->getSinkID()))->post();
124 fDone = true;
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000125 }
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000126 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000127
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000128 virtual void onSizeChange() {
129 this->INHERITED::onSizeChange();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000130
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000131 fNext->setSize(this->width(), this->height());
132 fPrev->setSize(this->width(), this->height());
rmistry@google.comae933ce2012-08-23 18:19:56 +0000133
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000134 SkScalar lr = 0, ud = 0;
135 if (fAnimationDirection & (kLeftDirection|kULDirection|kDLDirection))
136 lr = this->width();
137 if (fAnimationDirection & (kRightDirection|kURDirection|kDRDirection))
138 lr = -this->width();
139 if (fAnimationDirection & (kUpDirection|kULDirection|kURDirection))
140 ud = this->height();
141 if (fAnimationDirection & (kDownDirection|kDLDirection|kDRDirection))
142 ud = -this->height();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000143
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000144 fBegin[kPrevX] = fBegin[kPrevY] = 0;
145 fBegin[kNextX] = lr;
146 fBegin[kNextY] = ud;
147 fNext->setLocX(lr);
148 fNext->setLocY(ud);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000149
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000150 if (is_transition(fPrev))
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000151 lr = ud = 0;
152 fEnd[kPrevX] = -lr;
153 fEnd[kPrevY] = -ud;
154 fEnd[kNextX] = fEnd[kNextY] = 0;
robertphillips@google.comc6ce7502012-05-08 13:15:37 +0000155 SkScalar blend[] = { SkFloatToScalar(0.8f), SkFloatToScalar(0.0f),
156 SkFloatToScalar(0.0f), SK_Scalar1 };
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000157 fInterp.setKeyFrame(0, SkTime::GetMSecs(), fBegin, blend);
reed@google.com8d884752012-09-08 20:14:23 +0000158 fInterp.setKeyFrame(1, SkTime::GetMSecs()+kDurationMS, fEnd, blend);
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000159 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000160
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000161private:
162 enum {
163 kPrevX = 0,
164 kPrevY = 1,
165 kNextX = 2,
166 kNextY = 3
167 };
168 SkView* fPrev;
169 SkView* fNext;
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000170 bool fDone;
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000171 SkInterpolator fInterp;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000172
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000173 enum Direction{
174 kUpDirection = 1,
175 kURDirection = 1 << 1,
176 kRightDirection = 1 << 2,
177 kDRDirection = 1 << 3,
178 kDownDirection = 1 << 4,
179 kDLDirection = 1 << 5,
180 kLeftDirection = 1 << 6,
181 kULDirection = 1 << 7
182 };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000183
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000184 Direction fAnimationDirection;
185 SkScalar fBegin[4];
186 SkScalar fEnd[4];
rmistry@google.comae933ce2012-08-23 18:19:56 +0000187
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000188 typedef SampleView INHERITED;
189};
190
191SkView* create_transition(SkView* prev, SkView* next, int direction) {
djsollen@google.com62938202012-10-10 18:29:31 +0000192#ifdef SK_BUILD_FOR_ANDROID
skia.committer@gmail.comfc843592012-10-11 02:01:14 +0000193 // Disable transitions for Android
194 return next;
djsollen@google.com62938202012-10-10 18:29:31 +0000195#else
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000196 return SkNEW_ARGS(TransitionView, (prev, next, direction));
djsollen@google.com62938202012-10-10 18:29:31 +0000197#endif
epoger@google.com6a121782012-09-14 18:42:01 +0000198}