OLD | NEW |
| (Empty) |
1 /* | |
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 "TransitionView.h" | |
8 | |
9 #include "OverView.h" | |
10 #include "SampleCode.h" | |
11 #include "SkView.h" | |
12 #include "SkCanvas.h" | |
13 #include "SkTime.h" | |
14 #include "SkInterpolator.h" | |
15 | |
16 static const char gIsTransitionQuery[] = "is-transition"; | |
17 static const char gReplaceTransitionEvt[] = "replace-transition-view"; | |
18 | |
19 bool is_transition(SkView* view) { | |
20 SkEvent isTransition(gIsTransitionQuery); | |
21 return view->doQuery(&isTransition); | |
22 } | |
23 | |
24 class TransitionView : public SampleView { | |
25 enum { | |
26 // kDurationMS = 500 | |
27 kDurationMS = 1 | |
28 }; | |
29 | |
30 public: | |
31 TransitionView(SkView* prev, SkView* next, int direction) : fInterp(4, 2){ | |
32 fAnimationDirection = (Direction)(1 << (direction % 8)); | |
33 | |
34 fPrev = prev; | |
35 fPrev->setClipToBounds(false); | |
36 fPrev->setVisibleP(true); | |
37 (void)SampleView::SetUsePipe(fPrev, SkOSMenu::kOffState); | |
38 //Not calling unref because fPrev is assumed to have been created, so | |
39 //this will result in a transfer of ownership | |
40 this->attachChildToBack(fPrev); | |
41 | |
42 fNext = next; | |
43 fNext->setClipToBounds(true); | |
44 fNext->setVisibleP(true); | |
45 (void)SampleView::SetUsePipe(fNext, SkOSMenu::kOffState); | |
46 //Calling unref because next is a newly created view and TransitionView | |
47 //is now the sole owner of fNext | |
48 this->attachChildToFront(fNext)->unref(); | |
49 | |
50 fDone = false; | |
51 //SkDebugf("--created transition\n"); | |
52 } | |
53 | |
54 ~TransitionView(){ | |
55 //SkDebugf("--deleted transition\n"); | |
56 } | |
57 | |
58 virtual void requestMenu(SkOSMenu* menu) { | |
59 if (SampleView::IsSampleView(fNext)) | |
60 ((SampleView*)fNext)->requestMenu(menu); | |
61 } | |
62 | |
63 protected: | |
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 SkView* prev = fPrev; | |
81 prev->ref(); | |
82 | |
83 fPrev->detachFromParent(); | |
84 fPrev = (SkView*)SkEventSink::FindSink(evt.getFast32()); | |
85 (void)SampleView::SetUsePipe(fPrev, SkOSMenu::kOffState); | |
86 //attach the new fPrev and call unref to balance the ref in onDraw | |
87 this->attachChildToBack(fPrev)->unref(); | |
88 this->inval(NULL); | |
89 | |
90 SkASSERT(1 == prev->getRefCnt()); | |
91 prev->unref(); | |
92 return true; | |
93 } | |
94 if (evt.isType("transition-done")) { | |
95 fNext->setLoc(0, 0); | |
96 fNext->setClipToBounds(false); | |
97 SkEvent* evt = new SkEvent(gReplaceTransitionEvt, | |
98 this->getParent()->getSinkID()); | |
99 evt->setFast32(fNext->getSinkID()); | |
100 //increate ref count of fNext so it survives detachAllChildren | |
101 fNext->ref(); | |
102 this->detachAllChildren(); | |
103 evt->post(); | |
104 return true; | |
105 } | |
106 return this->INHERITED::onEvent(evt); | |
107 } | |
108 virtual void onDrawBackground(SkCanvas* canvas) {} | |
109 virtual void onDrawContent(SkCanvas* canvas) { | |
110 if (fDone) | |
111 return; | |
112 | |
113 if (is_overview(fNext) || is_overview(fPrev)) { | |
114 fPipeState = SkOSMenu::kOffState; | |
115 } | |
116 | |
117 SkScalar values[4]; | |
118 SkInterpolator::Result result = fInterp.timeToValues(SkTime::GetMSecs(),
values); | |
119 //SkDebugf("transition %x %d pipe:%d\n", this, result, fUsePipe); | |
120 //SkDebugf("%f %f %f %f %d\n", values[0], values[1], values[2], values[3
], result); | |
121 if (SkInterpolator::kNormal_Result == result) { | |
122 fPrev->setLocX(values[kPrevX]); | |
123 fPrev->setLocY(values[kPrevY]); | |
124 fNext->setLocX(values[kNextX]); | |
125 fNext->setLocY(values[kNextY]); | |
126 this->inval(NULL); | |
127 } | |
128 else { | |
129 (new SkEvent("transition-done", this->getSinkID()))->post(); | |
130 fDone = true; | |
131 } | |
132 } | |
133 | |
134 virtual void onSizeChange() { | |
135 this->INHERITED::onSizeChange(); | |
136 | |
137 fNext->setSize(this->width(), this->height()); | |
138 fPrev->setSize(this->width(), this->height()); | |
139 | |
140 SkScalar lr = 0, ud = 0; | |
141 if (fAnimationDirection & (kLeftDirection|kULDirection|kDLDirection)) | |
142 lr = this->width(); | |
143 if (fAnimationDirection & (kRightDirection|kURDirection|kDRDirection)) | |
144 lr = -this->width(); | |
145 if (fAnimationDirection & (kUpDirection|kULDirection|kURDirection)) | |
146 ud = this->height(); | |
147 if (fAnimationDirection & (kDownDirection|kDLDirection|kDRDirection)) | |
148 ud = -this->height(); | |
149 | |
150 fBegin[kPrevX] = fBegin[kPrevY] = 0; | |
151 fBegin[kNextX] = lr; | |
152 fBegin[kNextY] = ud; | |
153 fNext->setLocX(lr); | |
154 fNext->setLocY(ud); | |
155 | |
156 if (is_transition(fPrev)) | |
157 lr = ud = 0; | |
158 fEnd[kPrevX] = -lr; | |
159 fEnd[kPrevY] = -ud; | |
160 fEnd[kNextX] = fEnd[kNextY] = 0; | |
161 SkScalar blend[] = { 0.8f, 0.0f, | |
162 0.0f, SK_Scalar1 }; | |
163 fInterp.setKeyFrame(0, SkTime::GetMSecs(), fBegin, blend); | |
164 fInterp.setKeyFrame(1, SkTime::GetMSecs()+kDurationMS, fEnd, blend); | |
165 } | |
166 | |
167 private: | |
168 enum { | |
169 kPrevX = 0, | |
170 kPrevY = 1, | |
171 kNextX = 2, | |
172 kNextY = 3 | |
173 }; | |
174 SkView* fPrev; | |
175 SkView* fNext; | |
176 bool fDone; | |
177 SkInterpolator fInterp; | |
178 | |
179 enum Direction{ | |
180 kUpDirection = 1, | |
181 kURDirection = 1 << 1, | |
182 kRightDirection = 1 << 2, | |
183 kDRDirection = 1 << 3, | |
184 kDownDirection = 1 << 4, | |
185 kDLDirection = 1 << 5, | |
186 kLeftDirection = 1 << 6, | |
187 kULDirection = 1 << 7 | |
188 }; | |
189 | |
190 Direction fAnimationDirection; | |
191 SkScalar fBegin[4]; | |
192 SkScalar fEnd[4]; | |
193 | |
194 typedef SampleView INHERITED; | |
195 }; | |
196 | |
197 SkView* create_transition(SkView* prev, SkView* next, int direction) { | |
198 #ifdef SK_BUILD_FOR_ANDROID | |
199 // Disable transitions for Android | |
200 return next; | |
201 #else | |
202 return SkNEW_ARGS(TransitionView, (prev, next, direction)); | |
203 #endif | |
204 } | |
OLD | NEW |