• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* 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 
33 enum SkDisplayEvent_Properties {
34     SK_PROPERTY(key),
35     SK_PROPERTY(keys)
36 };
37 
38 #if SK_USE_CONDENSED_INFO == 0
39 
40 const 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 
53 DEFINE_GET_MEMBER(SkDisplayEvent);
54 
SkDisplayEvent()55 SkDisplayEvent::SkDisplayEvent() : code((SkKey) -1), disable(false),
56     kind(kUser), x(0), y(0), fLastCode((SkKey) -1), fMax((SkKey) -1), fTarget(NULL) {
57 }
58 
~SkDisplayEvent()59 SkDisplayEvent::~SkDisplayEvent() {
60     deleteMembers();
61 }
62 
add(SkAnimateMaker &,SkDisplayable * child)63 bool SkDisplayEvent::add(SkAnimateMaker& , SkDisplayable* child) {
64     *fChildren.append() = child;
65     return true;
66 }
67 
contains(SkDisplayable * match)68 bool 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 
contains(const SkString & match)76 SkDisplayable* 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 
deleteMembers()85 void 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
dumpEvent(SkAnimateMaker * maker)93 void 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 
enableEvent(SkAnimateMaker & maker)127 bool 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 
getProperty(int index,SkScriptValue * value) const160 bool 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 
onEndElement(SkAnimateMaker & maker)183 void 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 
populateInput(SkAnimateMaker & maker,const SkEvent & fEvent)197 void 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 
setProperty(int index,SkScriptValue & value)247 bool 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 
setPtr(char const *,void *)273 void SkMetaData::setPtr(char const*, void* ) {}
setS32(char const *,int)274 void SkMetaData::setS32(char const*, int ) {}
doEvent(SkEvent const &)275 bool SkEventSink::doEvent(SkEvent const& ) { return false; }
parse(SkStream &)276 bool SkXMLParser::parse(SkStream& ) { return false; }
SkXMLParserError()277 SkXMLParserError::SkXMLParserError( ) {}
setType(char const *,unsigned long)278 void SkEvent::setType(char const*, unsigned long ) {}
PostTime(SkEvent *,unsigned int,unsigned int)279 bool SkEvent::PostTime(SkEvent*, unsigned int, unsigned int ) { return false; }
SkEvent(char const *)280 SkEvent::SkEvent(char const* ) {}
SkEvent(SkEvent const &)281 SkEvent::SkEvent(SkEvent const& ) {}
SkEvent()282 SkEvent::SkEvent( ) {}
~SkEvent()283 SkEvent::~SkEvent( ) {}
onQuery(SkEvent *)284 bool SkEventSink::onQuery(SkEvent* ) { return false; }
SkEventSink()285 SkEventSink::SkEventSink( ) {}
~SkEventSink()286 SkEventSink::~SkEventSink( ) {}
parse(char const *,unsigned long)287 bool SkXMLParser::parse(char const*, unsigned long ) { return false; }
parse(SkDOM const &,SkDOMNode const *)288 bool SkXMLParser::parse(SkDOM const&, SkDOMNode const* ) { return false; }
Post(SkEvent *,unsigned int,unsigned int)289 bool SkEvent::Post(SkEvent*, unsigned int, unsigned int ) { return false; }
UnitTest()290 void SkParse::UnitTest( ) {}
findString(char const *) const291 const char* SkMetaData::findString(char const*) const {return 0;}
findPtr(char const *,void **) const292 bool SkMetaData::findPtr(char const*, void**) const {return false;}
findS32(char const *,int *) const293 bool SkMetaData::findS32(char const*, int*) const {return false;}
isType(char const *,unsigned long) const294 bool SkEvent::isType(char const*, unsigned long) const { return false; }
setString(char const *,char const *)295 void SkMetaData::setString(char const*, char const* ) {}
FindNamedColor(char const *,unsigned long,unsigned int *)296 const char* SkParse::FindNamedColor(char const*, unsigned long, unsigned int* ) {return false; }
next(SkMetaData::Type *,int *)297 const char* SkMetaData::Iter::next(SkMetaData::Type*, int* ) { return false; }
Iter(SkMetaData const &)298 SkMetaData::Iter::Iter(SkMetaData const& ) {}
findScalar(char const *,int *) const299 bool SkMetaData::findScalar(char const*, int*) const {return false;}
reset()300 void SkMetaData::reset( ) {}
setType(SkString const &)301 void SkEvent::setType(SkString const& ) {}
findBool(char const *,bool *) const302 bool SkMetaData::findBool(char const*, bool*) const {return false;}
getType(SkString *) const303 void SkEvent::getType(SkString*) const {}
endElement(char const *)304 bool SkXMLParser::endElement(char const* ) { return false; }
addAttribute(char const *,char const *)305 bool SkXMLParser::addAttribute(char const*, char const* ) { return false;}
startElement(char const *)306 bool SkXMLParser::startElement(char const* ) { return false;}
text(char const *,int)307 bool SkXMLParser::text(char const*, int ) { return false;}
onText(char const *,int)308 bool SkXMLParser::onText(char const*, int ) { return false;}
SkXMLParser(SkXMLParserError *)309 SkXMLParser::SkXMLParser(SkXMLParserError* ) {}
~SkXMLParser()310 SkXMLParser::~SkXMLParser( ) {}
~SkXMLParserError()311 SkXMLParserError::~SkXMLParserError( ) {}
getErrorString(SkString *) const312 void SkXMLParserError::getErrorString(SkString*) const {}
setSpacing(int,int)313 void SkTextBox::setSpacing(int, int ) {}
setSpacingAlign(SkTextBox::SpacingAlign)314 void SkTextBox::setSpacingAlign(SkTextBox::SpacingAlign ) {}
draw(SkCanvas *,char const *,unsigned long,SkPaint const &)315 void SkTextBox::draw(SkCanvas*, char const*, unsigned long, SkPaint const& ) {}
setBox(SkRect const &)316 void SkTextBox::setBox(SkRect const& ) {}
setMode(SkTextBox::Mode)317 void SkTextBox::setMode(SkTextBox::Mode ) {}
SkTextBox()318 SkTextBox::SkTextBox( ) {}
setScalar(char const *,int)319 void SkMetaData::setScalar(char const*, int ) {}
FindScalar(char const *,int *)320 const char* SkParse::FindScalar(char const*, int* ) {return 0; }
FindScalars(char const *,int *,int)321 const char* SkParse::FindScalars(char const*, int*, int ) {return 0; }
FindHex(char const *,unsigned int *)322 const char* SkParse::FindHex(char const*, unsigned int* ) {return 0; }
FindS32(char const *,int *)323 const char* SkParse::FindS32(char const*, int* ) {return 0; }
addAttribute(char const *,char const *)324 void SkXMLWriter::addAttribute(char const*, char const* ) {}
startElement(char const *)325 void SkXMLWriter::startElement(char const* ) {}
doEnd(SkXMLWriter::Elem *)326 void SkXMLWriter::doEnd(SkXMLWriter::Elem* ) {}
getEnd()327 SkXMLWriter::Elem* SkXMLWriter::getEnd( ) { return 0; }
doStart(char const *,unsigned long)328 bool SkXMLWriter::doStart(char const*, unsigned long ) { return false; }
SkXMLWriter(bool)329 SkXMLWriter::SkXMLWriter(bool ) {}
~SkXMLWriter()330 SkXMLWriter::~SkXMLWriter( ) {}
SkMetaData()331 SkMetaData::SkMetaData() {}
~SkMetaData()332 SkMetaData::~SkMetaData() {}
onEvent(SkEvent const &)333 bool SkEventSink::onEvent(SkEvent const&) {return false;}
onEndElement(char const *)334 bool SkXMLParser::onEndElement(char const*) {return false;}
onAddAttribute(char const *,char const *)335 bool SkXMLParser::onAddAttribute(char const*, char const*) {return false;}
onStartElement(char const *)336 bool SkXMLParser::onStartElement(char const*) {return false;}
writeHeader()337 void SkXMLWriter::writeHeader() {}
338 
339 #endif
340