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 #ifndef SkAnimator_DEFINED
     11 #define SkAnimator_DEFINED
     12 
     13 #include "SkScalar.h"
     14 #include "SkKey.h"
     15 #include "SkEventSink.h"
     16 
     17 class SkAnimateMaker;
     18 class SkCanvas;
     19 class SkDisplayable;
     20 class SkEvent;
     21 class SkExtras;
     22 struct SkMemberInfo;
     23 class SkPaint;
     24 struct SkRect;
     25 class SkStream;
     26 class SkTypedArray;
     27 class SkXMLParserError;
     28 class SkDOM;
     29 struct SkDOMNode;
     30 
     31 /** SkElementType is the type of element: a rectangle, a color, an animator, and so on.
     32     This enum is incomplete and will be fleshed out in a future release */
     33 enum SkElementType {
     34     kElementDummyType
     35 };
     36 /** SkFieldType is the type of field: a scalar, a string, an integer, a boolean, and so on.
     37     This enum is incomplete and will be fleshed out in a future release */
     38 enum SkFieldType {
     39     kFieldDummyType
     40 };
     41 
     42 /** \class SkAnimator
     43 
     44     The SkAnimator class decodes an XML stream into a display list. The
     45     display list can be drawn statically as a picture, or can drawn
     46     different elements at different times to form a moving animation.
     47 
     48     SkAnimator does not read the system time on its own; it relies on the
     49     caller to pass the current time. The caller can pause, speed up, or
     50     reverse the animation by varying the time passed in.
     51 
     52     The XML describing the display list must conform to the schema
     53     described by SkAnimateSchema.xsd.
     54 
     55     The XML must contain an <event> element to draw. Usually, it contains
     56     an <event kind="onload" /> block to add some drawing elements to the
     57     display list when the document is first decoded.
     58 
     59     Here's an "Hello World" XML sample:
     60 
     61     <screenplay>
     62         <event kind="onload" >
     63             <text text="Hello World" y="20" />
     64         </event>
     65     </screenplay>
     66 
     67     To read and draw this sample:
     68 
     69         // choose one of these two
     70         SkAnimator animator; // declare an animator instance on the stack
     71     //  SkAnimator* animator = new SkAnimator() // or one could instantiate the class
     72 
     73         // choose one of these three
     74         animator.decodeMemory(buffer, size); // to read from RAM
     75         animator.decodeStream(stream); // to read from a user-defined stream (e.g., a zip file)
     76         animator.decodeURI(filename); // to read from a web location, or from a local text file
     77 
     78         // to draw to the current window:
     79         SkCanvas canvas(getBitmap()); // create a canvas
     80         animator.draw(canvas, &paint, 0); // draw the scene
     81 */
     82 class SkAnimator : public SkEventSink {
     83 public:
     84     SkAnimator();
     85     virtual ~SkAnimator();
     86 
     87     /** Add a drawable extension to the graphics engine. Experimental.
     88         @param extras A derived class that implements methods that identify and instantiate the class
     89     */
     90     void addExtras(SkExtras* extras);
     91 
     92     /** Read in XML from a stream, and append it to the current
     93         animator. Returns false if an error was encountered.
     94         Error diagnostics are stored in fErrorCode and fLineNumber.
     95         @param stream  The stream to append.
     96         @return true if the XML was parsed successfully.
     97     */
     98     bool appendStream(SkStream* stream);
     99 
    100     /** Read in XML from memory. Returns true if the file can be
    101         read without error. Returns false if an error was encountered.
    102         Error diagnostics are stored in fErrorCode and fLineNumber.
    103         @param buffer  The XML text as UTF-8 characters.
    104         @param size  The XML text length in bytes.
    105         @return true if the XML was parsed successfully.
    106     */
    107     bool decodeMemory(const void* buffer, size_t size);
    108 
    109     /** Read in XML from a stream. Returns true if the file can be
    110         read without error. Returns false if an error was encountered.
    111         Error diagnostics are stored in fErrorCode and fLineNumber.
    112         @param stream  The stream containg the XML text as UTF-8 characters.
    113         @return true if the XML was parsed successfully.
    114     */
    115     virtual bool decodeStream(SkStream* stream);
    116 
    117     /** Parse the DOM tree starting at the specified node. Returns true if it can be
    118         parsed without error. Returns false if an error was encountered.
    119         Error diagnostics are stored in fErrorCode and fLineNumber.
    120         @return true if the DOM was parsed successfully.
    121     */
    122     virtual bool decodeDOM(const SkDOM&, const SkDOMNode*);
    123 
    124     /** Read in XML from a URI. Returns true if the file can be
    125         read without error. Returns false if an error was encountered.
    126         Error diagnostics are stored in fErrorCode and fLineNumber.
    127         @param uri The complete url path to be read (either ftp, http or https).
    128         @return true if the XML was parsed successfully.
    129     */
    130     bool decodeURI(const char uri[]);
    131 
    132     /** Pass a char event, usually a keyboard symbol, to the animator.
    133         This triggers events of the form <event kind="keyChar" key="... />
    134         @param ch  The character to match against <event> element "key"
    135             attributes.
    136         @return true if the event was dispatched successfully.
    137     */
    138     bool doCharEvent(SkUnichar ch);
    139 
    140     /** Experimental:
    141         Pass a mouse click event along with the mouse coordinates to
    142         the animator. This triggers events of the form <event kind="mouseDown" ... />
    143         and other mouse events.
    144         @param state The mouse state, described by SkView::Click::State : values are
    145         down == 0, moved == 1, up == 2
    146         @param x    The x-position of the mouse
    147         @param y The y-position of the mouse
    148         @return true if the event was dispatched successfully.
    149     */
    150     bool doClickEvent(int state, SkScalar x, SkScalar y);
    151 
    152     /** Pass a meta-key event, such as an arrow , to the animator.
    153         This triggers events of the form <event kind="keyPress" code="... />
    154         @param code  The key to match against <event> element "code"
    155             attributes.
    156         @return true if the event was dispatched successfully.
    157     */
    158     bool doKeyEvent(SkKey code);
    159     bool doKeyUpEvent(SkKey code);
    160 
    161     /** Send an event to the animator. The animator's clock is set
    162         relative to the current time.
    163         @return true if the event was dispatched successfully.
    164     */
    165     bool doUserEvent(const SkEvent& evt);
    166 
    167     /** The possible results from the draw function.
    168     */
    169     enum DifferenceType {
    170         kNotDifferent,
    171         kDifferent,
    172         kPartiallyDifferent
    173     };
    174     /** Draws one frame of the animation. The first call to draw always
    175         draws the initial frame of the animation. Subsequent calls draw
    176         the offset into the animation by
    177         subtracting the initial time from the current time.
    178         @param canvas  The canvas to draw into.
    179         @param paint     The paint to draw with.
    180         @param time  The offset into the current animation.
    181         @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
    182         kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
    183         redraw area.
    184     */
    185     DifferenceType draw(SkCanvas* canvas, SkPaint* paint, SkMSec time);
    186 
    187     /** Draws one frame of the animation, using a new Paint each time.
    188         The first call to draw always
    189         draws the initial frame of the animation. Subsequent calls draw
    190         the offset into the animation by
    191         subtracting the initial time from the current time.
    192         @param canvas  The canvas to draw into.
    193         @param time  The offset into the current animation.
    194         @return kNotDifferent if there are no active animations; kDifferent if there are active animations; and
    195         kPartiallyDifferent if the document contains an active <bounds> element that specifies a minimal
    196         redraw area.
    197     */
    198     DifferenceType draw(SkCanvas* canvas, SkMSec time);
    199 
    200     /** Experimental:
    201         Helper to choose whether to return a SkView::Click handler.
    202         @param x ignored
    203         @param y ignored
    204         @return true if a mouseDown event handler is enabled.
    205     */
    206     bool findClickEvent(SkScalar x, SkScalar y);
    207 
    208 
    209     /** Get the nested animator associated with this element, if any.
    210         Use this to access a movie's event sink, to send events to movies.
    211         @param element the value returned by getElement
    212         @return the internal animator.
    213     */
    214     const SkAnimator* getAnimator(const SkDisplayable* element) const;
    215 
    216     /** Returns the scalar value of the specified element's attribute[index]
    217         @param element the value returned by getElement
    218         @param field the value returned by getField
    219         @param index the array entry
    220         @return the integer value to retrieve, or SK_NaN32 if unsuccessful
    221     */
    222     int32_t getArrayInt(const SkDisplayable* element, const SkMemberInfo* field, int index);
    223 
    224     /** Returns the scalar value of the specified element's attribute[index]
    225         @param elementID is the value of the id attribute in the XML of this element
    226         @param fieldName specifies the name of the attribute
    227         @param index the array entry
    228         @return the integer value to retrieve, or SK_NaN32 if unsuccessful
    229     */
    230     int32_t getArrayInt(const char* elementID, const char* fieldName, int index);
    231 
    232     /** Returns the scalar value of the specified element's attribute[index]
    233         @param element the value returned by getElement
    234         @param field the value returned by getField
    235         @param index the array entry
    236         @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
    237     */
    238     SkScalar getArrayScalar(const SkDisplayable* element, const SkMemberInfo* field, int index);
    239 
    240     /** Returns the scalar value of the specified element's attribute[index]
    241         @param elementID is the value of the id attribute in the XML of this element
    242         @param fieldName specifies the name of the attribute
    243         @param index the array entry
    244         @return the scalar value to retrieve, or SK_ScalarNaN if unsuccessful
    245     */
    246     SkScalar getArrayScalar(const char* elementID, const char* fieldName, int index);
    247 
    248     /** Returns the string value of the specified element's attribute[index]
    249         @param element is a value returned by getElement
    250         @param field is a value returned by getField
    251         @param index the array entry
    252         @return the string value to retrieve, or null if unsuccessful
    253     */
    254     const char* getArrayString(const SkDisplayable* element, const SkMemberInfo* field, int index);
    255 
    256     /** Returns the string value of the specified element's attribute[index]
    257         @param elementID is the value of the id attribute in the XML of this element
    258         @param fieldName specifies the name of the attribute
    259         @param index the array entry
    260         @return the string value to retrieve, or null if unsuccessful
    261     */
    262     const char* getArrayString(const char* elementID, const char* fieldName, int index);
    263 
    264     /** Returns the XML element corresponding to the given ID.
    265         @param elementID is the value of the id attribute in the XML of this element
    266         @return the element matching the ID, or null if the element can't be found
    267     */
    268     const SkDisplayable* getElement(const char* elementID);
    269 
    270     /** Returns the element type corresponding to the XML element.
    271         The element type matches the element name; for instance, <line> returns kElement_LineType
    272         @param element is a value returned by getElement
    273         @return element type, or 0 if the element can't be found
    274     */
    275     SkElementType getElementType(const SkDisplayable* element);
    276 
    277     /** Returns the element type corresponding to the given ID.
    278         @param elementID is the value of the id attribute in the XML of this element
    279         @return element type, or 0 if the element can't be found
    280     */
    281     SkElementType getElementType(const char* elementID);
    282 
    283     /** Returns the XML field of the named attribute in the XML element.
    284         @param element is a value returned by getElement
    285         @param fieldName is the attribute to return
    286         @return the attribute matching the fieldName, or null if the element can't be found
    287     */
    288     const SkMemberInfo* getField(const SkDisplayable* element, const char* fieldName);
    289 
    290     /** Returns the XML field of the named attribute in the XML element matching the elementID.
    291         @param elementID is the value of the id attribute in the XML of this element
    292         @param fieldName is the attribute to return
    293         @return the attribute matching the fieldName, or null if the element can't be found
    294     */
    295     const SkMemberInfo* getField(const char* elementID, const char* fieldName);
    296 
    297     /** Returns the value type coresponding to the element's attribute.
    298         The value type matches the XML schema: and may be kField_BooleanType, kField_ScalarType, etc.
    299         @param field is a value returned by getField
    300         @return the attribute type, or 0 if the element can't be found
    301     */
    302     SkFieldType getFieldType(const SkMemberInfo* field);
    303 
    304     /** Returns the value type coresponding to the element's attribute.
    305         @param elementID is the value of the id attribute in the XML of this element
    306         @param fieldName specifies the name of the attribute
    307         @return the attribute type, or 0 if the element can't be found
    308     */
    309     SkFieldType getFieldType(const char* elementID, const char* fieldName);
    310 
    311     /** Returns the recommended animation interval. Returns zero if no
    312         interval is specified.
    313     */
    314     SkMSec getInterval();
    315 
    316     /** Returns the partial rectangle to invalidate after drawing. Call after draw() returns
    317     kIsPartiallyDifferent to do a mimimal inval(). */
    318     void getInvalBounds(SkRect* inval);
    319 
    320     /** Returns the details of any error encountered while parsing the XML.
    321     */
    322     const SkXMLParserError* getParserError();
    323 
    324     /** Returns the details of any error encountered while parsing the XML as string.
    325     */
    326     const char* getParserErrorString();
    327 
    328     /** Returns the scalar value of the specified element's attribute
    329         @param element is a value returned by getElement
    330         @param field is a value returned by getField
    331         @return the integer value to retrieve, or SK_NaN32 if not found
    332     */
    333     int32_t getInt(const SkDisplayable* element, const SkMemberInfo* field);
    334 
    335     /** Returns the scalar value of the specified element's attribute
    336         @param elementID is the value of the id attribute in the XML of this element
    337         @param fieldName specifies the name of the attribute
    338         @return the integer value to retrieve, or SK_NaN32 if not found
    339     */
    340     int32_t getInt(const char* elementID, const char* fieldName);
    341 
    342     /** Returns the scalar value of the specified element's attribute
    343         @param element is a value returned by getElement
    344         @param field is a value returned by getField
    345         @return the scalar value to retrieve, or SK_ScalarNaN if not found
    346     */
    347     SkScalar getScalar(const SkDisplayable* element, const SkMemberInfo* field);
    348 
    349     /** Returns the scalar value of the specified element's attribute
    350         @param elementID is the value of the id attribute in the XML of this element
    351         @param fieldName specifies the name of the attribute
    352         @return the scalar value to retrieve, or SK_ScalarNaN if not found
    353     */
    354     SkScalar getScalar(const char* elementID, const char* fieldName);
    355 
    356     /** Returns the string value of the specified element's attribute
    357         @param element is a value returned by getElement
    358         @param field is a value returned by getField
    359         @return the string value to retrieve, or null if not found
    360     */
    361     const char* getString(const SkDisplayable* element, const SkMemberInfo* field);
    362 
    363     /** Returns the string value of the specified element's attribute
    364         @param elementID is the value of the id attribute in the XML of this element
    365         @param fieldName specifies the name of the attribute
    366         @return the string value to retrieve, or null if not found
    367     */
    368     const char* getString(const char* elementID, const char* fieldName);
    369 
    370     /** Gets the file default directory of the URL base path set explicitly or by reading the last URL. */
    371     const char* getURIBase();
    372 
    373     /** Resets the animator to a newly created state with no animation data. */
    374     void initialize();
    375 
    376     /** Experimental. Resets any active animations so that the next time passed is treated as
    377         time zero. */
    378     void reset();
    379 
    380     /** Sets the scalar value of the specified element's attribute
    381         @param elementID is the value of the id attribute in the XML of this element
    382         @param fieldName specifies the name of the attribute
    383         @param array is the c-style array of integers
    384         @param count is the length of the array
    385         @return true if the value was set successfully
    386     */
    387     bool setArrayInt(const char* elementID, const char* fieldName, const int* array, int count);
    388 
    389     /** Sets the scalar value of the specified element's attribute
    390         @param elementID is the value of the id attribute in the XML of this element
    391         @param fieldName specifies the name of the attribute
    392         @param array is the c-style array of strings
    393         @param count is the length of the array
    394         @return true if the value was set successfully
    395     */
    396     bool setArrayString(const char* elementID, const char* fieldName, const char** array, int count);
    397 
    398     /** Sets the scalar value of the specified element's attribute
    399         @param elementID is the value of the id attribute in the XML of this element
    400         @param fieldName specifies the name of the attribute
    401         @param data the integer value to set
    402         @return true if the value was set successfully
    403     */
    404     bool setInt(const char* elementID, const char* fieldName, int32_t data);
    405 
    406     /** Sets the scalar value of the specified element's attribute
    407         @param elementID is the value of the id attribute in the XML of this element
    408         @param fieldName specifies the name of the attribute
    409         @param data the scalar value to set
    410         @return true if the value was set successfully
    411     */
    412     bool setScalar(const char* elementID, const char* fieldName, SkScalar data);
    413 
    414     /** Sets the string value of the specified element's attribute
    415         @param elementID is the value of the id attribute in the XML of this element
    416         @param fieldName specifies the name of the attribute
    417         @param data the string value to set
    418         @return true if the value was set successfully
    419     */
    420     bool setString(const char* elementID, const char* fieldName, const char* data);
    421 
    422     /** Sets the file default directory of the URL base path
    423         @param path the directory path
    424     */
    425     void setURIBase(const char* path);
    426 
    427     typedef void* Handler;
    428     // This guy needs to be exported to java, so don't make it virtual
    429     void setHostHandler(Handler handler) {
    430         this->onSetHostHandler(handler);
    431     }
    432 
    433     /** \class Timeline
    434     Returns current time to animator. To return a custom timeline, create a child
    435     class and override the getMSecs method.
    436     */
    437     class Timeline {
    438     public:
    439         virtual ~Timeline() {}
    440 
    441         /** Returns the current time in milliseconds */
    442         virtual SkMSec getMSecs() const = 0;
    443     };
    444 
    445     /** Sets a user class to return the current time to the animator.
    446         Optional; if not called, the system clock will be used by calling SkTime::GetMSecs instead.
    447         @param callBack the time function
    448     */
    449     void setTimeline(const Timeline& );
    450 
    451     static void Init(bool runUnitTests);
    452     static void Term();
    453 
    454     /** The event sink events generated by the animation are posted to.
    455         Screenplay also posts an inval event to this event sink after processing an
    456         event to force a redraw.
    457         @param target the event sink id
    458     */
    459     void setHostEventSinkID(SkEventSinkID hostID);
    460     SkEventSinkID getHostEventSinkID() const;
    461 
    462     // helper
    463     void setHostEventSink(SkEventSink* sink) {
    464         this->setHostEventSinkID(sink ? sink->getSinkID() : 0);
    465     }
    466 
    467     virtual void setJavaOwner(Handler owner);
    468 
    469 #ifdef SK_DEBUG
    470     virtual void eventDone(const SkEvent& evt);
    471     virtual bool isTrackingEvents();
    472     static bool NoLeaks();
    473 #endif
    474 
    475 protected:
    476     virtual void onSetHostHandler(Handler handler);
    477     virtual void onEventPost(SkEvent*, SkEventSinkID);
    478     virtual void onEventPostTime(SkEvent*, SkEventSinkID, SkMSec time);
    479 
    480 private:
    481 // helper functions for setters
    482     bool setArray(SkDisplayable* element, const SkMemberInfo* field, SkTypedArray array);
    483     bool setArray(const char* elementID, const char* fieldName, SkTypedArray array);
    484     bool setInt(SkDisplayable* element, const SkMemberInfo* field, int32_t data);
    485     bool setScalar(SkDisplayable* element, const SkMemberInfo* field, SkScalar data);
    486     bool setString(SkDisplayable* element, const SkMemberInfo* field, const char* data);
    487 
    488     virtual bool onEvent(const SkEvent&);
    489     SkAnimateMaker* fMaker;
    490     friend class SkAnimateMaker;
    491     friend class SkAnimatorScript;
    492     friend class SkAnimatorScript2;
    493     friend class SkApply;
    494     friend class SkDisplayMovie;
    495     friend class SkDisplayType;
    496     friend class SkPost;
    497     friend class SkXMLAnimatorWriter;
    498 };
    499 
    500 #endif
    501