grab from latest android



git-svn-id: http://skia.googlecode.com/svn/trunk@27 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/animator/SkDisplayEvent.cpp b/src/animator/SkDisplayEvent.cpp
new file mode 100644
index 0000000..6253cdf
--- /dev/null
+++ b/src/animator/SkDisplayEvent.cpp
@@ -0,0 +1,339 @@
+/* libs/graphics/animator/SkDisplayEvent.cpp
+**
+** Copyright 2006, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+
+#include "SkDisplayEvent.h"
+#include "SkAnimateMaker.h"
+#include "SkDisplayApply.h"
+#include "SkDisplayInput.h"
+#include "SkDisplayList.h"
+#ifdef SK_DEBUG
+#include "SkDump.h"
+#endif
+#include "SkEvent.h"
+#include "SkDisplayInput.h"
+#include "SkKey.h"
+#include "SkMetaData.h"
+#include "SkScript.h"
+#include "SkUtils.h"
+
+enum SkDisplayEvent_Properties {
+    SK_PROPERTY(key),
+    SK_PROPERTY(keys)
+};
+
+#if SK_USE_CONDENSED_INFO == 0
+
+const SkMemberInfo SkDisplayEvent::fInfo[] = {
+    SK_MEMBER(code, EventCode),
+    SK_MEMBER(disable, Boolean),
+    SK_MEMBER_PROPERTY(key, String), // a single key (also last key pressed)
+    SK_MEMBER_PROPERTY(keys, String), // a single key or dash-delimited range of keys
+    SK_MEMBER(kind, EventKind),
+    SK_MEMBER(target, String),
+    SK_MEMBER(x, Float),
+    SK_MEMBER(y, Float)
+};
+
+#endif
+
+DEFINE_GET_MEMBER(SkDisplayEvent);
+
+SkDisplayEvent::SkDisplayEvent() : code((SkKey) -1), disable(false),
+    kind(kUser), x(0), y(0), fLastCode((SkKey) -1), fMax((SkKey) -1), fTarget(NULL) {
+}
+
+SkDisplayEvent::~SkDisplayEvent() {
+    deleteMembers();
+}
+
+bool SkDisplayEvent::add(SkAnimateMaker& , SkDisplayable* child) { 
+    *fChildren.append() = child; 
+    return true; 
+}
+
+bool SkDisplayEvent::contains(SkDisplayable* match) {
+    for (int index = 0; index < fChildren.count(); index++) {
+        if (fChildren[index] == match || fChildren[index]->contains(match))
+            return true;
+    }
+    return false;
+}
+
+SkDisplayable* SkDisplayEvent::contains(const SkString& match) {
+    for (int index = 0; index < fChildren.count(); index++) {
+        SkDisplayable* child = fChildren[index];
+        if (child->contains(match))
+            return child;
+    }
+    return NULL;
+}
+
+void SkDisplayEvent::deleteMembers() {
+    for (int index = 0; index < fChildren.count(); index++) {
+        SkDisplayable* evt = fChildren[index];
+        delete evt;
+    }
+}
+
+#ifdef SK_DUMP_ENABLED
+void SkDisplayEvent::dumpEvent(SkAnimateMaker* maker) {
+    dumpBase(maker);
+    SkString str;
+    SkDump::GetEnumString(SkType_EventKind, kind, &str);
+    SkDebugf("kind=\"%s\" ", str.c_str());
+    if (kind == SkDisplayEvent::kKeyPress || kind == SkDisplayEvent::kKeyPressUp) {
+        if (code >= 0)
+            SkDump::GetEnumString(SkType_EventCode, code, &str);
+        else
+            str.set("none");
+        SkDebugf("code=\"%s\" ", str.c_str());
+    }
+    if (kind == SkDisplayEvent::kKeyChar) {
+        if (fMax != (SkKey) -1 && fMax != code)
+            SkDebugf("keys=\"%c - %c\" ", code, fMax);
+        else
+            SkDebugf("key=\"%c\" ", code);
+    }
+    if (fTarget != NULL) {
+        SkDebugf("target=\"%s\" ", fTarget->id);
+    }
+    if (kind >= SkDisplayEvent::kMouseDown && kind <= SkDisplayEvent::kMouseUp) {
+#ifdef SK_CAN_USE_FLOAT
+        SkDebugf("x=\"%g\" y=\"%g\" ", SkScalarToFloat(x), SkScalarToFloat(y));
+#else
+        SkDebugf("x=\"%x\" y=\"%x\" ", x, y);
+#endif
+    }
+    if (disable)
+        SkDebugf("disable=\"true\" ");
+    SkDebugf("/>\n");
+}
+#endif
+
+bool SkDisplayEvent::enableEvent(SkAnimateMaker& maker) 
+{
+    maker.fActiveEvent = this;
+    if (fChildren.count() == 0)
+        return false;
+    if (disable)
+        return false;
+#ifdef SK_DUMP_ENABLED
+    if (maker.fDumpEvents) {
+        SkDebugf("enable: ");
+        dumpEvent(&maker);
+    }
+#endif
+    SkDisplayList& displayList = maker.fDisplayList;
+    for (int index = 0; index < fChildren.count(); index++) {
+        SkDisplayable* displayable = fChildren[index];
+        if (displayable->isGroup()) {
+            SkTDDrawableArray* parentList = displayList.getDrawList();
+            *parentList->append() = (SkDrawable*) displayable;  // make it findable before children are enabled
+        }
+        if (displayable->enable(maker))
+            continue;
+        if (maker.hasError()) 
+            return true;
+        if (displayable->isDrawable() == false)
+            return true;    // error
+        SkDrawable* drawable = (SkDrawable*) displayable;
+        SkTDDrawableArray* parentList = displayList.getDrawList();
+        *parentList->append() = drawable;
+    }
+    return false;
+}
+
+bool SkDisplayEvent::getProperty(int index, SkScriptValue* value) const {
+    switch (index) {
+        case SK_PROPERTY(key):
+        case SK_PROPERTY(keys): {
+            value->fType = SkType_String;
+            char scratch[8];
+            SkKey convert = index == SK_PROPERTY(keys) ? code : fLastCode;
+            size_t size = convert > 0 ? SkUTF8_FromUnichar(convert, scratch) : 0;
+            fKeyString.set(scratch, size);
+            value->fOperand.fString = &fKeyString;
+            if (index != SK_PROPERTY(keys) || fMax == (SkKey) -1 || fMax == code)
+                break;
+            value->fOperand.fString->append("-");
+            size = SkUTF8_FromUnichar(fMax, scratch);
+            value->fOperand.fString->append(scratch, size);
+            } break;
+        default:
+            SkASSERT(0);
+            return false;
+    }
+    return true;
+}
+
+void SkDisplayEvent::onEndElement(SkAnimateMaker& maker)
+{
+    if (kind == kUser)
+        return;
+    maker.fEvents.addEvent(this);
+    if (kind == kOnEnd) {
+        bool found = maker.find(target.c_str(), &fTarget);
+        SkASSERT(found);
+        SkASSERT(fTarget && fTarget->isAnimate());
+        SkAnimateBase* animate = (SkAnimateBase*) fTarget;
+        animate->setHasEndEvent();
+    }
+}
+
+void SkDisplayEvent::populateInput(SkAnimateMaker& maker, const SkEvent& fEvent) {
+    const SkMetaData& meta = fEvent.getMetaData();
+    SkMetaData::Iter iter(meta);
+    SkMetaData::Type    type;
+    int number;
+    const char* name;
+    while ((name = iter.next(&type, &number)) != NULL) {
+        if (name[0] == '\0')
+            continue;
+        SkDisplayable* displayable;
+        SkInput* input;
+        for (int index = 0; index < fChildren.count(); index++) {
+            displayable = fChildren[index];
+            if (displayable->getType() != SkType_Input)
+                continue;
+            input = (SkInput*) displayable;
+            if (input->name.equals(name))
+                goto found;
+        }
+        if (!maker.find(name, &displayable) || displayable->getType() != SkType_Input)
+            continue;
+        input = (SkInput*) displayable;
+    found:
+        switch (type) {
+            case SkMetaData::kS32_Type:
+                meta.findS32(name, &input->fInt);
+                break;
+            case SkMetaData::kScalar_Type:
+                meta.findScalar(name, &input->fFloat);
+                break;
+            case SkMetaData::kPtr_Type:
+                SkASSERT(0);
+                break; // !!! not handled for now
+            case SkMetaData::kString_Type:
+                input->string.set(meta.findString(name));
+                break;
+            default:
+                SkASSERT(0);
+        }
+    }
+    // re-evaluate all animators that may have built their values from input strings
+    for (SkDisplayable** childPtr = fChildren.begin(); childPtr < fChildren.end(); childPtr++) {
+        SkDisplayable* displayable = *childPtr;
+        if (displayable->isApply() == false)
+            continue;
+        SkApply* apply = (SkApply*) displayable;
+        apply->refresh(maker);
+    }
+}
+
+bool SkDisplayEvent::setProperty(int index, SkScriptValue& value) {
+    SkASSERT(index == SK_PROPERTY(key) || index == SK_PROPERTY(keys));
+    SkASSERT(value.fType == SkType_String);
+    SkString* string = value.fOperand.fString;
+    const char* chars = string->c_str();
+    int count = SkUTF8_CountUnichars(chars);
+    SkASSERT(count >= 1);
+    code = (SkKey) SkUTF8_NextUnichar(&chars);
+    fMax = code;
+    SkASSERT(count == 1 || index == SK_PROPERTY(keys));
+    if (--count > 0) {
+        SkASSERT(*chars == '-');
+        chars++;
+        fMax = (SkKey) SkUTF8_NextUnichar(&chars);
+        SkASSERT(fMax >= code);
+    }
+    return true;
+}
+
+#ifdef ANDROID
+
+#include "SkMetaData.h"
+#include "SkParse.h"
+#include "SkTextBox.h"
+#include "SkXMLWriter.h"
+
+void SkMetaData::setPtr(char const*, void* ) {}
+void SkMetaData::setS32(char const*, int ) {}
+bool SkEventSink::doEvent(SkEvent const& ) { return false; }
+bool SkXMLParser::parse(SkStream& ) { return false; }
+SkXMLParserError::SkXMLParserError( ) {}
+void SkEvent::setType(char const*, unsigned long ) {}
+bool SkEvent::PostTime(SkEvent*, unsigned int, unsigned int ) { return false; }
+SkEvent::SkEvent(char const* ) {}
+SkEvent::SkEvent(SkEvent const& ) {}
+SkEvent::SkEvent( ) {}
+SkEvent::~SkEvent( ) {}
+bool SkEventSink::onQuery(SkEvent* ) { return false; }
+SkEventSink::SkEventSink( ) {}
+SkEventSink::~SkEventSink( ) {}
+bool SkXMLParser::parse(char const*, unsigned long ) { return false; }
+bool SkXMLParser::parse(SkDOM const&, SkDOMNode const* ) { return false; }
+bool SkEvent::Post(SkEvent*, unsigned int, unsigned int ) { return false; }
+void SkParse::UnitTest( ) {}
+const char* SkMetaData::findString(char const*) const {return 0;}
+bool SkMetaData::findPtr(char const*, void**) const {return false;}
+bool SkMetaData::findS32(char const*, int*) const {return false;}
+bool SkEvent::isType(char const*, unsigned long) const { return false; }
+void SkMetaData::setString(char const*, char const* ) {}
+const char* SkParse::FindNamedColor(char const*, unsigned long, unsigned int* ) {return false; }
+const char* SkMetaData::Iter::next(SkMetaData::Type*, int* ) { return false; }
+SkMetaData::Iter::Iter(SkMetaData const& ) {}
+bool SkMetaData::findScalar(char const*, int*) const {return false;}
+void SkMetaData::reset( ) {}
+void SkEvent::setType(SkString const& ) {}
+bool SkMetaData::findBool(char const*, bool*) const {return false;}
+void SkEvent::getType(SkString*) const {}
+bool SkXMLParser::endElement(char const* ) { return false; }
+bool SkXMLParser::addAttribute(char const*, char const* ) { return false;}
+bool SkXMLParser::startElement(char const* ) { return false;}
+bool SkXMLParser::text(char const*, int ) { return false;}
+bool SkXMLParser::onText(char const*, int ) { return false;}
+SkXMLParser::SkXMLParser(SkXMLParserError* ) {}
+SkXMLParser::~SkXMLParser( ) {}
+SkXMLParserError::~SkXMLParserError( ) {}
+void SkXMLParserError::getErrorString(SkString*) const {}
+void SkTextBox::setSpacing(int, int ) {}
+void SkTextBox::setSpacingAlign(SkTextBox::SpacingAlign ) {}
+void SkTextBox::draw(SkCanvas*, char const*, unsigned long, SkPaint const& ) {}
+void SkTextBox::setBox(SkRect const& ) {}
+void SkTextBox::setMode(SkTextBox::Mode ) {}
+SkTextBox::SkTextBox( ) {}
+void SkMetaData::setScalar(char const*, int ) {}
+const char* SkParse::FindScalar(char const*, int* ) {return 0; }
+const char* SkParse::FindScalars(char const*, int*, int ) {return 0; }
+const char* SkParse::FindHex(char const*, unsigned int* ) {return 0; }
+const char* SkParse::FindS32(char const*, int* ) {return 0; }
+void SkXMLWriter::addAttribute(char const*, char const* ) {}
+void SkXMLWriter::startElement(char const* ) {}
+void SkXMLWriter::doEnd(SkXMLWriter::Elem* ) {}
+SkXMLWriter::Elem* SkXMLWriter::getEnd( ) { return 0; }
+bool SkXMLWriter::doStart(char const*, unsigned long ) { return false; }
+SkXMLWriter::SkXMLWriter(bool ) {}
+SkXMLWriter::~SkXMLWriter( ) {}
+SkMetaData::SkMetaData() {}
+SkMetaData::~SkMetaData() {}
+bool SkEventSink::onEvent(SkEvent const&) {return false;}
+bool SkXMLParser::onEndElement(char const*) {return false;}
+bool SkXMLParser::onAddAttribute(char const*, char const*) {return false;}
+bool SkXMLParser::onStartElement(char const*) {return false;}
+void SkXMLWriter::writeHeader() {}
+
+#endif