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