diff -r 000000000000 -r 6474c204b198 gfx/skia/trunk/src/animator/SkDisplayEvent.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gfx/skia/trunk/src/animator/SkDisplayEvent.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,252 @@ + +/* + * Copyright 2006 The Android Open Source Project + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + + +#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::addChild(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) { + SkDebugf("x=\"%g\" y=\"%g\" ", SkScalarToFloat(x), SkScalarToFloat(y)); + } + 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) { + SkDEBUGCODE(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; +}