blob: 6253cdf6ab1bf835e1f195b6b56a7bde16a0cbb4 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001/* libs/graphics/animator/SkDisplayEvent.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9** http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#include "SkDisplayEvent.h"
19#include "SkAnimateMaker.h"
20#include "SkDisplayApply.h"
21#include "SkDisplayInput.h"
22#include "SkDisplayList.h"
23#ifdef SK_DEBUG
24#include "SkDump.h"
25#endif
26#include "SkEvent.h"
27#include "SkDisplayInput.h"
28#include "SkKey.h"
29#include "SkMetaData.h"
30#include "SkScript.h"
31#include "SkUtils.h"
32
33enum SkDisplayEvent_Properties {
34 SK_PROPERTY(key),
35 SK_PROPERTY(keys)
36};
37
38#if SK_USE_CONDENSED_INFO == 0
39
40const SkMemberInfo SkDisplayEvent::fInfo[] = {
41 SK_MEMBER(code, EventCode),
42 SK_MEMBER(disable, Boolean),
43 SK_MEMBER_PROPERTY(key, String), // a single key (also last key pressed)
44 SK_MEMBER_PROPERTY(keys, String), // a single key or dash-delimited range of keys
45 SK_MEMBER(kind, EventKind),
46 SK_MEMBER(target, String),
47 SK_MEMBER(x, Float),
48 SK_MEMBER(y, Float)
49};
50
51#endif
52
53DEFINE_GET_MEMBER(SkDisplayEvent);
54
55SkDisplayEvent::SkDisplayEvent() : code((SkKey) -1), disable(false),
56 kind(kUser), x(0), y(0), fLastCode((SkKey) -1), fMax((SkKey) -1), fTarget(NULL) {
57}
58
59SkDisplayEvent::~SkDisplayEvent() {
60 deleteMembers();
61}
62
63bool SkDisplayEvent::add(SkAnimateMaker& , SkDisplayable* child) {
64 *fChildren.append() = child;
65 return true;
66}
67
68bool SkDisplayEvent::contains(SkDisplayable* match) {
69 for (int index = 0; index < fChildren.count(); index++) {
70 if (fChildren[index] == match || fChildren[index]->contains(match))
71 return true;
72 }
73 return false;
74}
75
76SkDisplayable* SkDisplayEvent::contains(const SkString& match) {
77 for (int index = 0; index < fChildren.count(); index++) {
78 SkDisplayable* child = fChildren[index];
79 if (child->contains(match))
80 return child;
81 }
82 return NULL;
83}
84
85void SkDisplayEvent::deleteMembers() {
86 for (int index = 0; index < fChildren.count(); index++) {
87 SkDisplayable* evt = fChildren[index];
88 delete evt;
89 }
90}
91
92#ifdef SK_DUMP_ENABLED
93void SkDisplayEvent::dumpEvent(SkAnimateMaker* maker) {
94 dumpBase(maker);
95 SkString str;
96 SkDump::GetEnumString(SkType_EventKind, kind, &str);
97 SkDebugf("kind=\"%s\" ", str.c_str());
98 if (kind == SkDisplayEvent::kKeyPress || kind == SkDisplayEvent::kKeyPressUp) {
99 if (code >= 0)
100 SkDump::GetEnumString(SkType_EventCode, code, &str);
101 else
102 str.set("none");
103 SkDebugf("code=\"%s\" ", str.c_str());
104 }
105 if (kind == SkDisplayEvent::kKeyChar) {
106 if (fMax != (SkKey) -1 && fMax != code)
107 SkDebugf("keys=\"%c - %c\" ", code, fMax);
108 else
109 SkDebugf("key=\"%c\" ", code);
110 }
111 if (fTarget != NULL) {
112 SkDebugf("target=\"%s\" ", fTarget->id);
113 }
114 if (kind >= SkDisplayEvent::kMouseDown && kind <= SkDisplayEvent::kMouseUp) {
115#ifdef SK_CAN_USE_FLOAT
116 SkDebugf("x=\"%g\" y=\"%g\" ", SkScalarToFloat(x), SkScalarToFloat(y));
117#else
118 SkDebugf("x=\"%x\" y=\"%x\" ", x, y);
119#endif
120 }
121 if (disable)
122 SkDebugf("disable=\"true\" ");
123 SkDebugf("/>\n");
124}
125#endif
126
127bool SkDisplayEvent::enableEvent(SkAnimateMaker& maker)
128{
129 maker.fActiveEvent = this;
130 if (fChildren.count() == 0)
131 return false;
132 if (disable)
133 return false;
134#ifdef SK_DUMP_ENABLED
135 if (maker.fDumpEvents) {
136 SkDebugf("enable: ");
137 dumpEvent(&maker);
138 }
139#endif
140 SkDisplayList& displayList = maker.fDisplayList;
141 for (int index = 0; index < fChildren.count(); index++) {
142 SkDisplayable* displayable = fChildren[index];
143 if (displayable->isGroup()) {
144 SkTDDrawableArray* parentList = displayList.getDrawList();
145 *parentList->append() = (SkDrawable*) displayable; // make it findable before children are enabled
146 }
147 if (displayable->enable(maker))
148 continue;
149 if (maker.hasError())
150 return true;
151 if (displayable->isDrawable() == false)
152 return true; // error
153 SkDrawable* drawable = (SkDrawable*) displayable;
154 SkTDDrawableArray* parentList = displayList.getDrawList();
155 *parentList->append() = drawable;
156 }
157 return false;
158}
159
160bool SkDisplayEvent::getProperty(int index, SkScriptValue* value) const {
161 switch (index) {
162 case SK_PROPERTY(key):
163 case SK_PROPERTY(keys): {
164 value->fType = SkType_String;
165 char scratch[8];
166 SkKey convert = index == SK_PROPERTY(keys) ? code : fLastCode;
167 size_t size = convert > 0 ? SkUTF8_FromUnichar(convert, scratch) : 0;
168 fKeyString.set(scratch, size);
169 value->fOperand.fString = &fKeyString;
170 if (index != SK_PROPERTY(keys) || fMax == (SkKey) -1 || fMax == code)
171 break;
172 value->fOperand.fString->append("-");
173 size = SkUTF8_FromUnichar(fMax, scratch);
174 value->fOperand.fString->append(scratch, size);
175 } break;
176 default:
177 SkASSERT(0);
178 return false;
179 }
180 return true;
181}
182
183void SkDisplayEvent::onEndElement(SkAnimateMaker& maker)
184{
185 if (kind == kUser)
186 return;
187 maker.fEvents.addEvent(this);
188 if (kind == kOnEnd) {
189 bool found = maker.find(target.c_str(), &fTarget);
190 SkASSERT(found);
191 SkASSERT(fTarget && fTarget->isAnimate());
192 SkAnimateBase* animate = (SkAnimateBase*) fTarget;
193 animate->setHasEndEvent();
194 }
195}
196
197void SkDisplayEvent::populateInput(SkAnimateMaker& maker, const SkEvent& fEvent) {
198 const SkMetaData& meta = fEvent.getMetaData();
199 SkMetaData::Iter iter(meta);
200 SkMetaData::Type type;
201 int number;
202 const char* name;
203 while ((name = iter.next(&type, &number)) != NULL) {
204 if (name[0] == '\0')
205 continue;
206 SkDisplayable* displayable;
207 SkInput* input;
208 for (int index = 0; index < fChildren.count(); index++) {
209 displayable = fChildren[index];
210 if (displayable->getType() != SkType_Input)
211 continue;
212 input = (SkInput*) displayable;
213 if (input->name.equals(name))
214 goto found;
215 }
216 if (!maker.find(name, &displayable) || displayable->getType() != SkType_Input)
217 continue;
218 input = (SkInput*) displayable;
219 found:
220 switch (type) {
221 case SkMetaData::kS32_Type:
222 meta.findS32(name, &input->fInt);
223 break;
224 case SkMetaData::kScalar_Type:
225 meta.findScalar(name, &input->fFloat);
226 break;
227 case SkMetaData::kPtr_Type:
228 SkASSERT(0);
229 break; // !!! not handled for now
230 case SkMetaData::kString_Type:
231 input->string.set(meta.findString(name));
232 break;
233 default:
234 SkASSERT(0);
235 }
236 }
237 // re-evaluate all animators that may have built their values from input strings
238 for (SkDisplayable** childPtr = fChildren.begin(); childPtr < fChildren.end(); childPtr++) {
239 SkDisplayable* displayable = *childPtr;
240 if (displayable->isApply() == false)
241 continue;
242 SkApply* apply = (SkApply*) displayable;
243 apply->refresh(maker);
244 }
245}
246
247bool SkDisplayEvent::setProperty(int index, SkScriptValue& value) {
248 SkASSERT(index == SK_PROPERTY(key) || index == SK_PROPERTY(keys));
249 SkASSERT(value.fType == SkType_String);
250 SkString* string = value.fOperand.fString;
251 const char* chars = string->c_str();
252 int count = SkUTF8_CountUnichars(chars);
253 SkASSERT(count >= 1);
254 code = (SkKey) SkUTF8_NextUnichar(&chars);
255 fMax = code;
256 SkASSERT(count == 1 || index == SK_PROPERTY(keys));
257 if (--count > 0) {
258 SkASSERT(*chars == '-');
259 chars++;
260 fMax = (SkKey) SkUTF8_NextUnichar(&chars);
261 SkASSERT(fMax >= code);
262 }
263 return true;
264}
265
266#ifdef ANDROID
267
268#include "SkMetaData.h"
269#include "SkParse.h"
270#include "SkTextBox.h"
271#include "SkXMLWriter.h"
272
273void SkMetaData::setPtr(char const*, void* ) {}
274void SkMetaData::setS32(char const*, int ) {}
275bool SkEventSink::doEvent(SkEvent const& ) { return false; }
276bool SkXMLParser::parse(SkStream& ) { return false; }
277SkXMLParserError::SkXMLParserError( ) {}
278void SkEvent::setType(char const*, unsigned long ) {}
279bool SkEvent::PostTime(SkEvent*, unsigned int, unsigned int ) { return false; }
280SkEvent::SkEvent(char const* ) {}
281SkEvent::SkEvent(SkEvent const& ) {}
282SkEvent::SkEvent( ) {}
283SkEvent::~SkEvent( ) {}
284bool SkEventSink::onQuery(SkEvent* ) { return false; }
285SkEventSink::SkEventSink( ) {}
286SkEventSink::~SkEventSink( ) {}
287bool SkXMLParser::parse(char const*, unsigned long ) { return false; }
288bool SkXMLParser::parse(SkDOM const&, SkDOMNode const* ) { return false; }
289bool SkEvent::Post(SkEvent*, unsigned int, unsigned int ) { return false; }
290void SkParse::UnitTest( ) {}
291const char* SkMetaData::findString(char const*) const {return 0;}
292bool SkMetaData::findPtr(char const*, void**) const {return false;}
293bool SkMetaData::findS32(char const*, int*) const {return false;}
294bool SkEvent::isType(char const*, unsigned long) const { return false; }
295void SkMetaData::setString(char const*, char const* ) {}
296const char* SkParse::FindNamedColor(char const*, unsigned long, unsigned int* ) {return false; }
297const char* SkMetaData::Iter::next(SkMetaData::Type*, int* ) { return false; }
298SkMetaData::Iter::Iter(SkMetaData const& ) {}
299bool SkMetaData::findScalar(char const*, int*) const {return false;}
300void SkMetaData::reset( ) {}
301void SkEvent::setType(SkString const& ) {}
302bool SkMetaData::findBool(char const*, bool*) const {return false;}
303void SkEvent::getType(SkString*) const {}
304bool SkXMLParser::endElement(char const* ) { return false; }
305bool SkXMLParser::addAttribute(char const*, char const* ) { return false;}
306bool SkXMLParser::startElement(char const* ) { return false;}
307bool SkXMLParser::text(char const*, int ) { return false;}
308bool SkXMLParser::onText(char const*, int ) { return false;}
309SkXMLParser::SkXMLParser(SkXMLParserError* ) {}
310SkXMLParser::~SkXMLParser( ) {}
311SkXMLParserError::~SkXMLParserError( ) {}
312void SkXMLParserError::getErrorString(SkString*) const {}
313void SkTextBox::setSpacing(int, int ) {}
314void SkTextBox::setSpacingAlign(SkTextBox::SpacingAlign ) {}
315void SkTextBox::draw(SkCanvas*, char const*, unsigned long, SkPaint const& ) {}
316void SkTextBox::setBox(SkRect const& ) {}
317void SkTextBox::setMode(SkTextBox::Mode ) {}
318SkTextBox::SkTextBox( ) {}
319void SkMetaData::setScalar(char const*, int ) {}
320const char* SkParse::FindScalar(char const*, int* ) {return 0; }
321const char* SkParse::FindScalars(char const*, int*, int ) {return 0; }
322const char* SkParse::FindHex(char const*, unsigned int* ) {return 0; }
323const char* SkParse::FindS32(char const*, int* ) {return 0; }
324void SkXMLWriter::addAttribute(char const*, char const* ) {}
325void SkXMLWriter::startElement(char const* ) {}
326void SkXMLWriter::doEnd(SkXMLWriter::Elem* ) {}
327SkXMLWriter::Elem* SkXMLWriter::getEnd( ) { return 0; }
328bool SkXMLWriter::doStart(char const*, unsigned long ) { return false; }
329SkXMLWriter::SkXMLWriter(bool ) {}
330SkXMLWriter::~SkXMLWriter( ) {}
331SkMetaData::SkMetaData() {}
332SkMetaData::~SkMetaData() {}
333bool SkEventSink::onEvent(SkEvent const&) {return false;}
334bool SkXMLParser::onEndElement(char const*) {return false;}
335bool SkXMLParser::onAddAttribute(char const*, char const*) {return false;}
336bool SkXMLParser::onStartElement(char const*) {return false;}
337void SkXMLWriter::writeHeader() {}
338
339#endif