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