Home | History | Annotate | Download | only in animator
      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::add(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 #ifdef SK_CAN_USE_FLOAT
    108         SkDebugf("x=\"%g\" y=\"%g\" ", SkScalarToFloat(x), SkScalarToFloat(y));
    109 #else
    110         SkDebugf("x=\"%x\" y=\"%x\" ", x, y);
    111 #endif
    112     }
    113     if (disable)
    114         SkDebugf("disable=\"true\" ");
    115     SkDebugf("/>\n");
    116 }
    117 #endif
    118 
    119 bool SkDisplayEvent::enableEvent(SkAnimateMaker& maker)
    120 {
    121     maker.fActiveEvent = this;
    122     if (fChildren.count() == 0)
    123         return false;
    124     if (disable)
    125         return false;
    126 #ifdef SK_DUMP_ENABLED
    127     if (maker.fDumpEvents) {
    128         SkDebugf("enable: ");
    129         dumpEvent(&maker);
    130     }
    131 #endif
    132     SkDisplayList& displayList = maker.fDisplayList;
    133     for (int index = 0; index < fChildren.count(); index++) {
    134         SkDisplayable* displayable = fChildren[index];
    135         if (displayable->isGroup()) {
    136             SkTDDrawableArray* parentList = displayList.getDrawList();
    137             *parentList->append() = (SkDrawable*) displayable;  // make it findable before children are enabled
    138         }
    139         if (displayable->enable(maker))
    140             continue;
    141         if (maker.hasError())
    142             return true;
    143         if (displayable->isDrawable() == false)
    144             return true;    // error
    145         SkDrawable* drawable = (SkDrawable*) displayable;
    146         SkTDDrawableArray* parentList = displayList.getDrawList();
    147         *parentList->append() = drawable;
    148     }
    149     return false;
    150 }
    151 
    152 bool SkDisplayEvent::getProperty(int index, SkScriptValue* value) const {
    153     switch (index) {
    154         case SK_PROPERTY(key):
    155         case SK_PROPERTY(keys): {
    156             value->fType = SkType_String;
    157             char scratch[8];
    158             SkKey convert = index == SK_PROPERTY(keys) ? code : fLastCode;
    159             size_t size = convert > 0 ? SkUTF8_FromUnichar(convert, scratch) : 0;
    160             fKeyString.set(scratch, size);
    161             value->fOperand.fString = &fKeyString;
    162             if (index != SK_PROPERTY(keys) || fMax == (SkKey) -1 || fMax == code)
    163                 break;
    164             value->fOperand.fString->append("-");
    165             size = SkUTF8_FromUnichar(fMax, scratch);
    166             value->fOperand.fString->append(scratch, size);
    167             } break;
    168         default:
    169             SkASSERT(0);
    170             return false;
    171     }
    172     return true;
    173 }
    174 
    175 void SkDisplayEvent::onEndElement(SkAnimateMaker& maker)
    176 {
    177     if (kind == kUser)
    178         return;
    179     maker.fEvents.addEvent(this);
    180     if (kind == kOnEnd) {
    181         bool found = maker.find(target.c_str(), &fTarget);
    182         SkASSERT(found);
    183         SkASSERT(fTarget && fTarget->isAnimate());
    184         SkAnimateBase* animate = (SkAnimateBase*) fTarget;
    185         animate->setHasEndEvent();
    186     }
    187 }
    188 
    189 void SkDisplayEvent::populateInput(SkAnimateMaker& maker, const SkEvent& fEvent) {
    190     const SkMetaData& meta = fEvent.getMetaData();
    191     SkMetaData::Iter iter(meta);
    192     SkMetaData::Type    type;
    193     int number;
    194     const char* name;
    195     while ((name = iter.next(&type, &number)) != NULL) {
    196         if (name[0] == '\0')
    197             continue;
    198         SkDisplayable* displayable;
    199         SkInput* input;
    200         for (int index = 0; index < fChildren.count(); index++) {
    201             displayable = fChildren[index];
    202             if (displayable->getType() != SkType_Input)
    203                 continue;
    204             input = (SkInput*) displayable;
    205             if (input->name.equals(name))
    206                 goto found;
    207         }
    208         if (!maker.find(name, &displayable) || displayable->getType() != SkType_Input)
    209             continue;
    210         input = (SkInput*) displayable;
    211     found:
    212         switch (type) {
    213             case SkMetaData::kS32_Type:
    214                 meta.findS32(name, &input->fInt);
    215                 break;
    216             case SkMetaData::kScalar_Type:
    217                 meta.findScalar(name, &input->fFloat);
    218                 break;
    219             case SkMetaData::kPtr_Type:
    220                 SkASSERT(0);
    221                 break; // !!! not handled for now
    222             case SkMetaData::kString_Type:
    223                 input->string.set(meta.findString(name));
    224                 break;
    225             default:
    226                 SkASSERT(0);
    227         }
    228     }
    229     // re-evaluate all animators that may have built their values from input strings
    230     for (SkDisplayable** childPtr = fChildren.begin(); childPtr < fChildren.end(); childPtr++) {
    231         SkDisplayable* displayable = *childPtr;
    232         if (displayable->isApply() == false)
    233             continue;
    234         SkApply* apply = (SkApply*) displayable;
    235         apply->refresh(maker);
    236     }
    237 }
    238 
    239 bool SkDisplayEvent::setProperty(int index, SkScriptValue& value) {
    240     SkASSERT(index == SK_PROPERTY(key) || index == SK_PROPERTY(keys));
    241     SkASSERT(value.fType == SkType_String);
    242     SkString* string = value.fOperand.fString;
    243     const char* chars = string->c_str();
    244     int count = SkUTF8_CountUnichars(chars);
    245     SkASSERT(count >= 1);
    246     code = (SkKey) SkUTF8_NextUnichar(&chars);
    247     fMax = code;
    248     SkASSERT(count == 1 || index == SK_PROPERTY(keys));
    249     if (--count > 0) {
    250         SkASSERT(*chars == '-');
    251         chars++;
    252         fMax = (SkKey) SkUTF8_NextUnichar(&chars);
    253         SkASSERT(fMax >= code);
    254     }
    255     return true;
    256 }
    257 
    258 #ifdef SK_BUILD_FOR_ANDROID
    259 
    260 #include "SkMetaData.h"
    261 #include "SkParse.h"
    262 #include "SkTextBox.h"
    263 #include "SkXMLWriter.h"
    264 
    265 void SkMetaData::setPtr(char const*, void*, PtrProc ) {}
    266 void SkMetaData::setS32(char const*, int ) {}
    267 bool SkEventSink::doEvent(SkEvent const& ) { return false; }
    268 bool SkXMLParser::parse(SkStream& ) { return false; }
    269 SkXMLParserError::SkXMLParserError( ) {}
    270 void SkEvent::setType(char const*, size_t ) {}
    271 void SkEvent::postTime(SkMSec) {}
    272 SkEvent::SkEvent(char const*, SkEventSinkID) {}
    273 SkEvent::SkEvent(SkEvent const&) {}
    274 SkEvent::SkEvent( ) {}
    275 SkEvent::~SkEvent( ) {}
    276 bool SkEventSink::onQuery(SkEvent* ) { return false; }
    277 SkEventSink::SkEventSink( ) {}
    278 SkEventSink::~SkEventSink( ) {}
    279 bool SkXMLParser::parse(char const*, size_t ) { return false; }
    280 bool SkXMLParser::parse(SkDOM const&, SkDOMNode const* ) { return false; }
    281 //void SkParse::UnitTest( ) {}
    282 const char* SkMetaData::findString(char const* ) const {return 0;}
    283 bool SkMetaData::findPtr(char const*, void**, PtrProc* ) const {return false;}
    284 bool SkMetaData::findS32(char const*, int* ) const {return false;}
    285 bool SkEvent::isType(char const*, size_t ) const { return false; }
    286 void SkMetaData::setString(char const*, char const* ) {}
    287 const char* SkParse::FindNamedColor(char const*, size_t, SkColor* ) {return false; }
    288 const char* SkMetaData::Iter::next(SkMetaData::Type*, int* ) { return false; }
    289 SkMetaData::Iter::Iter(SkMetaData const& ) {}
    290 bool SkMetaData::findScalar(char const*, SkScalar* ) const {return false;}
    291 void SkMetaData::reset( ) {}
    292 void SkEvent::setType(SkString const& ) {}
    293 bool SkMetaData::findBool(char const*, bool* ) const {return false;}
    294 void SkEvent::getType(SkString*) const {}
    295 bool SkXMLParser::endElement(char const* ) { return false; }
    296 bool SkXMLParser::addAttribute(char const*, char const* ) { return false;}
    297 bool SkXMLParser::startElement(char const* ) { return false;}
    298 bool SkXMLParser::text(char const*, int ) { return false;}
    299 bool SkXMLParser::onText(char const*, int ) { return false;}
    300 SkXMLParser::SkXMLParser(SkXMLParserError* ) {}
    301 SkXMLParser::~SkXMLParser( ) {}
    302 SkXMLParserError::~SkXMLParserError( ) {}
    303 void SkXMLParserError::getErrorString(SkString*) const {}
    304 void SkTextBox::setSpacing(SkScalar, SkScalar ) {}
    305 void SkTextBox::setSpacingAlign(SkTextBox::SpacingAlign ) {}
    306 void SkTextBox::draw(SkCanvas*, char const*, size_t, SkPaint const& ) {}
    307 void SkTextBox::setBox(SkRect const& ) {}
    308 void SkTextBox::setMode(SkTextBox::Mode ) {}
    309 SkTextBox::SkTextBox( ) {}
    310 void SkMetaData::setScalar(char const*, SkScalar ) {}
    311 const char* SkParse::FindScalar(char const*, SkScalar* ) {return 0; }
    312 const char* SkParse::FindScalars(char const*, SkScalar*, int ) {return 0; }
    313 const char* SkParse::FindHex(char const*, unsigned int* ) {return 0; }
    314 const char* SkParse::FindS32(char const*, int* ) {return 0; }
    315 void SkXMLWriter::addAttribute(char const*, char const* ) {}
    316 void SkXMLWriter::startElement(char const* ) {}
    317 void SkXMLWriter::doEnd(SkXMLWriter::Elem* ) {}
    318 SkXMLWriter::Elem* SkXMLWriter::getEnd( ) { return 0; }
    319 bool SkXMLWriter::doStart(char const*, size_t ) { return false; }
    320 SkXMLWriter::SkXMLWriter(bool ) {}
    321 SkXMLWriter::~SkXMLWriter( ) {}
    322 SkMetaData::SkMetaData() {}
    323 SkMetaData::~SkMetaData() {}
    324 bool SkEventSink::onEvent(SkEvent const&) {return false;}
    325 bool SkXMLParser::onEndElement(char const*) {return false;}
    326 bool SkXMLParser::onAddAttribute(char const*, char const*) {return false;}
    327 bool SkXMLParser::onStartElement(char const*) {return false;}
    328 void SkXMLWriter::writeHeader() {}
    329 
    330 #endif
    331