blob: 95938ef8d0d7e05471f85702ce7385fc0ffa075a [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 */
7#include "SampleCode.h"
8#include "SkView.h"
9#include "SkCanvas.h"
10#include "SkTime.h"
11#include "SkInterpolator.h"
12
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000013extern bool is_overview(SkView* view);
14
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000015static const char gIsTransitionQuery[] = "is-transition";
16static const char gReplaceTransitionEvt[] = "replace-transition-view";
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000017
caryclark@google.com02939ce2012-06-06 12:09:51 +000018static bool is_transition(SkView* view) {
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000019 SkEvent isTransition(gIsTransitionQuery);
20 return view->doQuery(&isTransition);
21}
22
23class TransitionView : public SampleView {
24public:
25 TransitionView(SkView* prev, SkView* next, int direction) : fInterp(4, 2){
26 fAnimationDirection = (Direction)(1 << (direction % 8));
rmistry@google.comae933ce2012-08-23 18:19:56 +000027
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000028 fPrev = prev;
29 fPrev->setClipToBounds(false);
30 fPrev->setVisibleP(true);
scroggo@google.comb073d922012-06-08 15:35:03 +000031 (void)SampleView::SetUsePipe(fPrev, SkOSMenu::kOffState);
rmistry@google.comae933ce2012-08-23 18:19:56 +000032 //Not calling unref because fPrev is assumed to have been created, so
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000033 //this will result in a transfer of ownership
34 this->attachChildToBack(fPrev);
rmistry@google.comae933ce2012-08-23 18:19:56 +000035
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000036 fNext = next;
37 fNext->setClipToBounds(true);
38 fNext->setVisibleP(true);
scroggo@google.comb073d922012-06-08 15:35:03 +000039 (void)SampleView::SetUsePipe(fNext, SkOSMenu::kOffState);
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000040 //Calling unref because next is a newly created view and TransitionView
41 //is now the sole owner of fNext
42 this->attachChildToFront(fNext)->unref();
rmistry@google.comae933ce2012-08-23 18:19:56 +000043
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000044 fDone = false;
45 //SkDebugf("--created transition\n");
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000046 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000047
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000048 ~TransitionView(){
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000049 //SkDebugf("--deleted transition\n");
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000050 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000051
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000052 virtual void requestMenu(SkOSMenu* menu) {
53 if (SampleView::IsSampleView(fNext))
54 ((SampleView*)fNext)->requestMenu(menu);
55 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000056
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000057protected:
58 virtual bool onQuery(SkEvent* evt) {
59 if (SampleCode::TitleQ(*evt)) {
60 SkString title;
61 if (SampleCode::RequestTitle(fNext, &title)) {
62 SampleCode::TitleR(evt, title.c_str());
63 return true;
64 }
65 return false;
66 }
67 if (evt->isType(gIsTransitionQuery)) {
68 return true;
69 }
70 return this->INHERITED::onQuery(evt);
71 }
72 virtual bool onEvent(const SkEvent& evt) {
73 if (evt.isType(gReplaceTransitionEvt)) {
74 fPrev->detachFromParent();
75 fPrev = (SkView*)SkEventSink::FindSink(evt.getFast32());
scroggo@google.comb073d922012-06-08 15:35:03 +000076 (void)SampleView::SetUsePipe(fPrev, SkOSMenu::kOffState);
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000077 //attach the new fPrev and call unref to balance the ref in onDraw
78 this->attachChildToBack(fPrev)->unref();
79 this->inval(NULL);
80 return true;
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000081 }
82 if (evt.isType("transition-done")) {
83 fNext->setLoc(0, 0);
84 fNext->setClipToBounds(false);
rmistry@google.comae933ce2012-08-23 18:19:56 +000085 SkEvent* evt = new SkEvent(gReplaceTransitionEvt,
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000086 this->getParent()->getSinkID());
87 evt->setFast32(fNext->getSinkID());
88 //increate ref count of fNext so it survives detachAllChildren
89 fNext->ref();
90 this->detachAllChildren();
91 evt->post();
92 return true;
93 }
yangsu@google.comdb03eaa2011-08-08 15:37:23 +000094 return this->INHERITED::onEvent(evt);
95 }
96 virtual void onDrawBackground(SkCanvas* canvas) {}
97 virtual void onDrawContent(SkCanvas* canvas) {
yangsu@google.comef7bdfa2011-08-12 14:27:47 +000098 if (fDone)
99 return;
100
101 if (is_overview(fNext) || is_overview(fPrev)) {
scroggo@google.comb073d922012-06-08 15:35:03 +0000102 fPipeState = SkOSMenu::kOffState;
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000103 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000104
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000105 SkScalar values[4];
106 SkInterpolator::Result result = fInterp.timeToValues(SkTime::GetMSecs(), values);
107 //SkDebugf("transition %x %d pipe:%d\n", this, result, fUsePipe);
108 //SkDebugf("%f %f %f %f %d\n", values[0], values[1], values[2], values[3], result);
109 if (SkInterpolator::kNormal_Result == result) {
110 fPrev->setLocX(values[kPrevX]);
111 fPrev->setLocY(values[kPrevY]);
112 fNext->setLocX(values[kNextX]);
113 fNext->setLocY(values[kNextY]);
114 this->inval(NULL);
115 }
116 else {
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000117 (new SkEvent("transition-done", this->getSinkID()))->post();
118 fDone = true;
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000119 }
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000120 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000121
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000122 virtual void onSizeChange() {
123 this->INHERITED::onSizeChange();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000124
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000125 fNext->setSize(this->width(), this->height());
126 fPrev->setSize(this->width(), this->height());
rmistry@google.comae933ce2012-08-23 18:19:56 +0000127
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000128 SkScalar lr = 0, ud = 0;
129 if (fAnimationDirection & (kLeftDirection|kULDirection|kDLDirection))
130 lr = this->width();
131 if (fAnimationDirection & (kRightDirection|kURDirection|kDRDirection))
132 lr = -this->width();
133 if (fAnimationDirection & (kUpDirection|kULDirection|kURDirection))
134 ud = this->height();
135 if (fAnimationDirection & (kDownDirection|kDLDirection|kDRDirection))
136 ud = -this->height();
rmistry@google.comae933ce2012-08-23 18:19:56 +0000137
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000138 fBegin[kPrevX] = fBegin[kPrevY] = 0;
139 fBegin[kNextX] = lr;
140 fBegin[kNextY] = ud;
141 fNext->setLocX(lr);
142 fNext->setLocY(ud);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000143
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000144 if (is_transition(fPrev))
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000145 lr = ud = 0;
146 fEnd[kPrevX] = -lr;
147 fEnd[kPrevY] = -ud;
148 fEnd[kNextX] = fEnd[kNextY] = 0;
robertphillips@google.comc6ce7502012-05-08 13:15:37 +0000149 SkScalar blend[] = { SkFloatToScalar(0.8f), SkFloatToScalar(0.0f),
150 SkFloatToScalar(0.0f), SK_Scalar1 };
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000151 fInterp.setKeyFrame(0, SkTime::GetMSecs(), fBegin, blend);
152 fInterp.setKeyFrame(1, SkTime::GetMSecs()+500, fEnd, blend);
153 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000154
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000155private:
156 enum {
157 kPrevX = 0,
158 kPrevY = 1,
159 kNextX = 2,
160 kNextY = 3
161 };
162 SkView* fPrev;
163 SkView* fNext;
yangsu@google.comef7bdfa2011-08-12 14:27:47 +0000164 bool fDone;
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000165 SkInterpolator fInterp;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000166
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000167 enum Direction{
168 kUpDirection = 1,
169 kURDirection = 1 << 1,
170 kRightDirection = 1 << 2,
171 kDRDirection = 1 << 3,
172 kDownDirection = 1 << 4,
173 kDLDirection = 1 << 5,
174 kLeftDirection = 1 << 6,
175 kULDirection = 1 << 7
176 };
rmistry@google.comae933ce2012-08-23 18:19:56 +0000177
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000178 Direction fAnimationDirection;
179 SkScalar fBegin[4];
180 SkScalar fEnd[4];
rmistry@google.comae933ce2012-08-23 18:19:56 +0000181
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000182 typedef SampleView INHERITED;
183};
184
caryclark@google.com02939ce2012-06-06 12:09:51 +0000185// FIXME: this should go in a header
186SkView* create_transition(SkView* prev, SkView* next, int direction);
187
yangsu@google.comdb03eaa2011-08-08 15:37:23 +0000188SkView* create_transition(SkView* prev, SkView* next, int direction) {
189 return SkNEW_ARGS(TransitionView, (prev, next, direction));
caryclark@google.com02939ce2012-06-06 12:09:51 +0000190};