|
1 |
|
2 /* |
|
3 * Copyright 2006 The Android Open Source Project |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 |
|
10 #include "SkDisplayEvent.h" |
|
11 #include "SkAnimateMaker.h" |
|
12 #include "SkDisplayApply.h" |
|
13 #include "SkDisplayInput.h" |
|
14 #include "SkDisplayList.h" |
|
15 #ifdef SK_DEBUG |
|
16 #include "SkDump.h" |
|
17 #endif |
|
18 #include "SkEvent.h" |
|
19 #include "SkDisplayInput.h" |
|
20 #include "SkKey.h" |
|
21 #include "SkMetaData.h" |
|
22 #include "SkScript.h" |
|
23 #include "SkUtils.h" |
|
24 |
|
25 enum SkDisplayEvent_Properties { |
|
26 SK_PROPERTY(key), |
|
27 SK_PROPERTY(keys) |
|
28 }; |
|
29 |
|
30 #if SK_USE_CONDENSED_INFO == 0 |
|
31 |
|
32 const SkMemberInfo SkDisplayEvent::fInfo[] = { |
|
33 SK_MEMBER(code, EventCode), |
|
34 SK_MEMBER(disable, Boolean), |
|
35 SK_MEMBER_PROPERTY(key, String), // a single key (also last key pressed) |
|
36 SK_MEMBER_PROPERTY(keys, String), // a single key or dash-delimited range of keys |
|
37 SK_MEMBER(kind, EventKind), |
|
38 SK_MEMBER(target, String), |
|
39 SK_MEMBER(x, Float), |
|
40 SK_MEMBER(y, Float) |
|
41 }; |
|
42 |
|
43 #endif |
|
44 |
|
45 DEFINE_GET_MEMBER(SkDisplayEvent); |
|
46 |
|
47 SkDisplayEvent::SkDisplayEvent() : code((SkKey) -1), disable(false), |
|
48 kind(kUser), x(0), y(0), fLastCode((SkKey) -1), fMax((SkKey) -1), fTarget(NULL) { |
|
49 } |
|
50 |
|
51 SkDisplayEvent::~SkDisplayEvent() { |
|
52 deleteMembers(); |
|
53 } |
|
54 |
|
55 bool SkDisplayEvent::addChild(SkAnimateMaker& , SkDisplayable* child) { |
|
56 *fChildren.append() = child; |
|
57 return true; |
|
58 } |
|
59 |
|
60 bool SkDisplayEvent::contains(SkDisplayable* match) { |
|
61 for (int index = 0; index < fChildren.count(); index++) { |
|
62 if (fChildren[index] == match || fChildren[index]->contains(match)) |
|
63 return true; |
|
64 } |
|
65 return false; |
|
66 } |
|
67 |
|
68 SkDisplayable* SkDisplayEvent::contains(const SkString& match) { |
|
69 for (int index = 0; index < fChildren.count(); index++) { |
|
70 SkDisplayable* child = fChildren[index]; |
|
71 if (child->contains(match)) |
|
72 return child; |
|
73 } |
|
74 return NULL; |
|
75 } |
|
76 |
|
77 void SkDisplayEvent::deleteMembers() { |
|
78 for (int index = 0; index < fChildren.count(); index++) { |
|
79 SkDisplayable* evt = fChildren[index]; |
|
80 delete evt; |
|
81 } |
|
82 } |
|
83 |
|
84 #ifdef SK_DUMP_ENABLED |
|
85 void SkDisplayEvent::dumpEvent(SkAnimateMaker* maker) { |
|
86 dumpBase(maker); |
|
87 SkString str; |
|
88 SkDump::GetEnumString(SkType_EventKind, kind, &str); |
|
89 SkDebugf("kind=\"%s\" ", str.c_str()); |
|
90 if (kind == SkDisplayEvent::kKeyPress || kind == SkDisplayEvent::kKeyPressUp) { |
|
91 if (code >= 0) |
|
92 SkDump::GetEnumString(SkType_EventCode, code, &str); |
|
93 else |
|
94 str.set("none"); |
|
95 SkDebugf("code=\"%s\" ", str.c_str()); |
|
96 } |
|
97 if (kind == SkDisplayEvent::kKeyChar) { |
|
98 if (fMax != (SkKey) -1 && fMax != code) |
|
99 SkDebugf("keys=\"%c - %c\" ", code, fMax); |
|
100 else |
|
101 SkDebugf("key=\"%c\" ", code); |
|
102 } |
|
103 if (fTarget != NULL) { |
|
104 SkDebugf("target=\"%s\" ", fTarget->id); |
|
105 } |
|
106 if (kind >= SkDisplayEvent::kMouseDown && kind <= SkDisplayEvent::kMouseUp) { |
|
107 SkDebugf("x=\"%g\" y=\"%g\" ", SkScalarToFloat(x), SkScalarToFloat(y)); |
|
108 } |
|
109 if (disable) |
|
110 SkDebugf("disable=\"true\" "); |
|
111 SkDebugf("/>\n"); |
|
112 } |
|
113 #endif |
|
114 |
|
115 bool SkDisplayEvent::enableEvent(SkAnimateMaker& maker) |
|
116 { |
|
117 maker.fActiveEvent = this; |
|
118 if (fChildren.count() == 0) |
|
119 return false; |
|
120 if (disable) |
|
121 return false; |
|
122 #ifdef SK_DUMP_ENABLED |
|
123 if (maker.fDumpEvents) { |
|
124 SkDebugf("enable: "); |
|
125 dumpEvent(&maker); |
|
126 } |
|
127 #endif |
|
128 SkDisplayList& displayList = maker.fDisplayList; |
|
129 for (int index = 0; index < fChildren.count(); index++) { |
|
130 SkDisplayable* displayable = fChildren[index]; |
|
131 if (displayable->isGroup()) { |
|
132 SkTDDrawableArray* parentList = displayList.getDrawList(); |
|
133 *parentList->append() = (SkDrawable*) displayable; // make it findable before children are enabled |
|
134 } |
|
135 if (displayable->enable(maker)) |
|
136 continue; |
|
137 if (maker.hasError()) |
|
138 return true; |
|
139 if (displayable->isDrawable() == false) |
|
140 return true; // error |
|
141 SkDrawable* drawable = (SkDrawable*) displayable; |
|
142 SkTDDrawableArray* parentList = displayList.getDrawList(); |
|
143 *parentList->append() = drawable; |
|
144 } |
|
145 return false; |
|
146 } |
|
147 |
|
148 bool SkDisplayEvent::getProperty(int index, SkScriptValue* value) const { |
|
149 switch (index) { |
|
150 case SK_PROPERTY(key): |
|
151 case SK_PROPERTY(keys): { |
|
152 value->fType = SkType_String; |
|
153 char scratch[8]; |
|
154 SkKey convert = index == SK_PROPERTY(keys) ? code : fLastCode; |
|
155 size_t size = convert > 0 ? SkUTF8_FromUnichar(convert, scratch) : 0; |
|
156 fKeyString.set(scratch, size); |
|
157 value->fOperand.fString = &fKeyString; |
|
158 if (index != SK_PROPERTY(keys) || fMax == (SkKey) -1 || fMax == code) |
|
159 break; |
|
160 value->fOperand.fString->append("-"); |
|
161 size = SkUTF8_FromUnichar(fMax, scratch); |
|
162 value->fOperand.fString->append(scratch, size); |
|
163 } break; |
|
164 default: |
|
165 SkASSERT(0); |
|
166 return false; |
|
167 } |
|
168 return true; |
|
169 } |
|
170 |
|
171 void SkDisplayEvent::onEndElement(SkAnimateMaker& maker) |
|
172 { |
|
173 if (kind == kUser) |
|
174 return; |
|
175 maker.fEvents.addEvent(this); |
|
176 if (kind == kOnEnd) { |
|
177 SkDEBUGCODE(bool found = ) maker.find(target.c_str(), &fTarget); |
|
178 SkASSERT(found); |
|
179 SkASSERT(fTarget && fTarget->isAnimate()); |
|
180 SkAnimateBase* animate = (SkAnimateBase*) fTarget; |
|
181 animate->setHasEndEvent(); |
|
182 } |
|
183 } |
|
184 |
|
185 void SkDisplayEvent::populateInput(SkAnimateMaker& maker, const SkEvent& fEvent) { |
|
186 const SkMetaData& meta = fEvent.getMetaData(); |
|
187 SkMetaData::Iter iter(meta); |
|
188 SkMetaData::Type type; |
|
189 int number; |
|
190 const char* name; |
|
191 while ((name = iter.next(&type, &number)) != NULL) { |
|
192 if (name[0] == '\0') |
|
193 continue; |
|
194 SkDisplayable* displayable; |
|
195 SkInput* input; |
|
196 for (int index = 0; index < fChildren.count(); index++) { |
|
197 displayable = fChildren[index]; |
|
198 if (displayable->getType() != SkType_Input) |
|
199 continue; |
|
200 input = (SkInput*) displayable; |
|
201 if (input->name.equals(name)) |
|
202 goto found; |
|
203 } |
|
204 if (!maker.find(name, &displayable) || displayable->getType() != SkType_Input) |
|
205 continue; |
|
206 input = (SkInput*) displayable; |
|
207 found: |
|
208 switch (type) { |
|
209 case SkMetaData::kS32_Type: |
|
210 meta.findS32(name, &input->fInt); |
|
211 break; |
|
212 case SkMetaData::kScalar_Type: |
|
213 meta.findScalar(name, &input->fFloat); |
|
214 break; |
|
215 case SkMetaData::kPtr_Type: |
|
216 SkASSERT(0); |
|
217 break; // !!! not handled for now |
|
218 case SkMetaData::kString_Type: |
|
219 input->string.set(meta.findString(name)); |
|
220 break; |
|
221 default: |
|
222 SkASSERT(0); |
|
223 } |
|
224 } |
|
225 // re-evaluate all animators that may have built their values from input strings |
|
226 for (SkDisplayable** childPtr = fChildren.begin(); childPtr < fChildren.end(); childPtr++) { |
|
227 SkDisplayable* displayable = *childPtr; |
|
228 if (displayable->isApply() == false) |
|
229 continue; |
|
230 SkApply* apply = (SkApply*) displayable; |
|
231 apply->refresh(maker); |
|
232 } |
|
233 } |
|
234 |
|
235 bool SkDisplayEvent::setProperty(int index, SkScriptValue& value) { |
|
236 SkASSERT(index == SK_PROPERTY(key) || index == SK_PROPERTY(keys)); |
|
237 SkASSERT(value.fType == SkType_String); |
|
238 SkString* string = value.fOperand.fString; |
|
239 const char* chars = string->c_str(); |
|
240 int count = SkUTF8_CountUnichars(chars); |
|
241 SkASSERT(count >= 1); |
|
242 code = (SkKey) SkUTF8_NextUnichar(&chars); |
|
243 fMax = code; |
|
244 SkASSERT(count == 1 || index == SK_PROPERTY(keys)); |
|
245 if (--count > 0) { |
|
246 SkASSERT(*chars == '-'); |
|
247 chars++; |
|
248 fMax = (SkKey) SkUTF8_NextUnichar(&chars); |
|
249 SkASSERT(fMax >= code); |
|
250 } |
|
251 return true; |
|
252 } |