Home | History | Annotate | Download | only in animator
      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 
     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 
     59 SkDisplayEvent::~SkDisplayEvent() {
     60     deleteMembers();
     61 }
     62 
     63 bool SkDisplayEvent::add(SkAnimateMaker& , SkDisplayable* child) {
     64     *fChildren.append() = child;
     65     return true;
     66 }
     67 
     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 
     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 
     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
     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 
    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 
    160 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 
    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 
    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 
    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 
    273 void SkMetaData::setPtr(char const*, void* ) {}
    274 void SkMetaData::setS32(char const*, int ) {}
    275 bool SkEventSink::doEvent(SkEvent const& ) { return false; }
    276 bool SkXMLParser::parse(SkStream& ) { return false; }
    277 SkXMLParserError::SkXMLParserError( ) {}
    278 void SkEvent::setType(char const*, unsigned long ) {}
    279 bool SkEvent::PostTime(SkEvent*, unsigned int, unsigned int ) { return false; }
    280 SkEvent::SkEvent(char const* ) {}
    281 SkEvent::SkEvent(SkEvent const& ) {}
    282 SkEvent::SkEvent( ) {}
    283 SkEvent::~SkEvent( ) {}
    284 bool SkEventSink::onQuery(SkEvent* ) { return false; }
    285 SkEventSink::SkEventSink( ) {}
    286 SkEventSink::~SkEventSink( ) {}
    287 bool SkXMLParser::parse(char const*, unsigned long ) { return false; }
    288 bool SkXMLParser::parse(SkDOM const&, SkDOMNode const* ) { return false; }
    289 bool SkEvent::Post(SkEvent*, unsigned int, unsigned int ) { return false; }
    290 void SkParse::UnitTest( ) {}
    291 const char* SkMetaData::findString(char const*) const {return 0;}
    292 bool SkMetaData::findPtr(char const*, void**) const {return false;}
    293 bool SkMetaData::findS32(char const*, int*) const {return false;}
    294 bool SkEvent::isType(char const*, unsigned long) const { return false; }
    295 void SkMetaData::setString(char const*, char const* ) {}
    296 const char* SkParse::FindNamedColor(char const*, unsigned long, unsigned int* ) {return false; }
    297 const char* SkMetaData::Iter::next(SkMetaData::Type*, int* ) { return false; }
    298 SkMetaData::Iter::Iter(SkMetaData const& ) {}
    299 bool SkMetaData::findScalar(char const*, int*) const {return false;}
    300 void SkMetaData::reset( ) {}
    301 void SkEvent::setType(SkString const& ) {}
    302 bool SkMetaData::findBool(char const*, bool*) const {return false;}
    303 void SkEvent::getType(SkString*) const {}
    304 bool SkXMLParser::endElement(char const* ) { return false; }
    305 bool SkXMLParser::addAttribute(char const*, char const* ) { return false;}
    306 bool SkXMLParser::startElement(char const* ) { return false;}
    307 bool SkXMLParser::text(char const*, int ) { return false;}
    308 bool SkXMLParser::onText(char const*, int ) { return false;}
    309 SkXMLParser::SkXMLParser(SkXMLParserError* ) {}
    310 SkXMLParser::~SkXMLParser( ) {}
    311 SkXMLParserError::~SkXMLParserError( ) {}
    312 void SkXMLParserError::getErrorString(SkString*) const {}
    313 void SkTextBox::setSpacing(int, int ) {}
    314 void SkTextBox::setSpacingAlign(SkTextBox::SpacingAlign ) {}
    315 void SkTextBox::draw(SkCanvas*, char const*, unsigned long, SkPaint const& ) {}
    316 void SkTextBox::setBox(SkRect const& ) {}
    317 void SkTextBox::setMode(SkTextBox::Mode ) {}
    318 SkTextBox::SkTextBox( ) {}
    319 void SkMetaData::setScalar(char const*, int ) {}
    320 const char* SkParse::FindScalar(char const*, int* ) {return 0; }
    321 const char* SkParse::FindScalars(char const*, int*, int ) {return 0; }
    322 const char* SkParse::FindHex(char const*, unsigned int* ) {return 0; }
    323 const char* SkParse::FindS32(char const*, int* ) {return 0; }
    324 void SkXMLWriter::addAttribute(char const*, char const* ) {}
    325 void SkXMLWriter::startElement(char const* ) {}
    326 void SkXMLWriter::doEnd(SkXMLWriter::Elem* ) {}
    327 SkXMLWriter::Elem* SkXMLWriter::getEnd( ) { return 0; }
    328 bool SkXMLWriter::doStart(char const*, unsigned long ) { return false; }
    329 SkXMLWriter::SkXMLWriter(bool ) {}
    330 SkXMLWriter::~SkXMLWriter( ) {}
    331 SkMetaData::SkMetaData() {}
    332 SkMetaData::~SkMetaData() {}
    333 bool SkEventSink::onEvent(SkEvent const&) {return false;}
    334 bool SkXMLParser::onEndElement(char const*) {return false;}
    335 bool SkXMLParser::onAddAttribute(char const*, char const*) {return false;}
    336 bool SkXMLParser::onStartElement(char const*) {return false;}
    337 void SkXMLWriter::writeHeader() {}
    338 
    339 #endif
    340