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 SkEventSink_DEFINED
18#define SkEventSink_DEFINED
19
20#include "SkRefCnt.h"
21#include "SkEvent.h"
22
23struct SkTagList;
24
25/** \class SkEventSink
26
27    SkEventSink is the base class for all objects that receive SkEvents.
28*/
29class SkEventSink : public SkRefCnt {
30public:
31            SkEventSink();
32    virtual ~SkEventSink();
33
34    /** Returns this eventsink's unique ID. Use this to post SkEvents to
35        this eventsink.
36    */
37    SkEventSinkID getSinkID() const { return fID; }
38
39    /** Call this to pass an event to this object for processing. Returns true if the
40        event was handled.
41    */
42    bool doEvent(const SkEvent&);
43    /** Returns true if the sink (or one of its subclasses) understands the event as a query.
44        If so, the sink may modify the event to communicate its "answer".
45    */
46    bool doQuery(SkEvent* query);
47
48    /** Add sinkID to the list of listeners, to receive events from calls to sendToListeners()
49        and postToListeners(). If sinkID already exists in the listener list, no change is made.
50    */
51    void    addListenerID(SkEventSinkID sinkID);
52    /** Copy listeners from one event sink to another, typically from parent to child.
53        @param from the event sink to copy the listeners from
54    */
55    void copyListeners(const SkEventSink& from);
56    /** Remove sinkID from the list of listeners. If sinkID does not appear in the list,
57        no change is made.
58    */
59    void    removeListenerID(SkEventSinkID);
60    /** Returns true if there are 1 or more listeners attached to this eventsink
61    */
62    bool    hasListeners() const;
63    /** Posts a copy of evt to each of the eventsinks in the lisener list.
64    */
65    void    postToListeners(const SkEvent& evt, SkMSec delay = 0);
66
67    enum EventResult {
68        kHandled_EventResult,       //!< the eventsink returned true from its doEvent method
69        kNotHandled_EventResult,    //!< the eventsink returned false from its doEvent method
70        kSinkNotFound_EventResult   //!< no matching eventsink was found for the event's getSink().
71    };
72    /** DoEvent handles searching for an eventsink object that matches the targetID.
73        If one is found, it calls the sink's doEvent method, returning
74        either kHandled_EventResult or kNotHandled_EventResult. If no matching
75        eventsink is found, kSinkNotFound_EventResult is returned.
76    */
77    static EventResult DoEvent(const SkEvent&, SkEventSinkID targetID);
78
79    /** Returns the matching eventsink, or null if not found
80    */
81    static SkEventSink* FindSink(SkEventSinkID);
82
83protected:
84    /** Override this to handle events in your subclass. Be sure to call the inherited version
85        for events that you don't handle.
86    */
87    virtual bool onEvent(const SkEvent&);
88    virtual bool onQuery(SkEvent*);
89
90    SkTagList*  findTagList(U8CPU tag) const;
91    void        addTagList(SkTagList*);
92    void        removeTagList(U8CPU tag);
93
94private:
95    SkEventSinkID   fID;
96    SkTagList*      fTagHead;
97
98    // for our private link-list
99    SkEventSink*    fNextSink;
100};
101
102#endif
103
104