michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkEventSink_DEFINED michael@0: #define SkEventSink_DEFINED michael@0: michael@0: #include "SkRefCnt.h" michael@0: #include "SkEvent.h" michael@0: michael@0: struct SkTagList; michael@0: michael@0: /** \class SkEventSink michael@0: michael@0: SkEventSink is the base class for all objects that receive SkEvents. michael@0: */ michael@0: class SkEventSink : public SkRefCnt { michael@0: public: michael@0: SK_DECLARE_INST_COUNT(SkEventSink) michael@0: michael@0: SkEventSink(); michael@0: virtual ~SkEventSink(); michael@0: michael@0: /** michael@0: * Returns this eventsink's unique ID. Use this to post SkEvents to michael@0: * this eventsink. michael@0: */ michael@0: SkEventSinkID getSinkID() const { return fID; } michael@0: michael@0: /** michael@0: * Call this to pass an event to this object for processing. Returns true if the michael@0: * event was handled. michael@0: */ michael@0: bool doEvent(const SkEvent&); michael@0: michael@0: /** Returns true if the sink (or one of its subclasses) understands the event as a query. michael@0: If so, the sink may modify the event to communicate its "answer". michael@0: */ michael@0: bool doQuery(SkEvent* query); michael@0: michael@0: /** michael@0: * Add sinkID to the list of listeners, to receive events from calls to sendToListeners() michael@0: * and postToListeners(). If sinkID already exists in the listener list, no change is made. michael@0: */ michael@0: void addListenerID(SkEventSinkID sinkID); michael@0: michael@0: /** michael@0: * Copy listeners from one event sink to another, typically from parent to child. michael@0: * @param from the event sink to copy the listeners from michael@0: */ michael@0: void copyListeners(const SkEventSink& from); michael@0: michael@0: /** michael@0: * Remove sinkID from the list of listeners. If sinkID does not appear in the list, michael@0: * no change is made. michael@0: */ michael@0: void removeListenerID(SkEventSinkID); michael@0: michael@0: /** michael@0: * Returns true if there are 1 or more listeners attached to this eventsink michael@0: */ michael@0: bool hasListeners() const; michael@0: michael@0: /** michael@0: * Posts a copy of evt to each of the eventsinks in the lisener list. michael@0: * This ignores the targetID and target proc in evt. michael@0: */ michael@0: void postToListeners(const SkEvent& evt, SkMSec delay = 0); michael@0: michael@0: enum EventResult { michael@0: kHandled_EventResult, //!< the eventsink returned true from its doEvent method michael@0: kNotHandled_EventResult, //!< the eventsink returned false from its doEvent method michael@0: kSinkNotFound_EventResult //!< no matching eventsink was found for the event's getSink(). michael@0: }; michael@0: michael@0: /** michael@0: * DoEvent handles dispatching the event to its target ID or proc. michael@0: */ michael@0: static EventResult DoEvent(const SkEvent&); michael@0: michael@0: /** michael@0: * Returns the matching eventsink, or null if not found michael@0: */ michael@0: static SkEventSink* FindSink(SkEventSinkID); michael@0: michael@0: protected: michael@0: /** Override this to handle events in your subclass. Be sure to call the inherited version michael@0: for events that you don't handle. michael@0: */ michael@0: virtual bool onEvent(const SkEvent&); michael@0: virtual bool onQuery(SkEvent*); michael@0: michael@0: SkTagList* findTagList(U8CPU tag) const; michael@0: void addTagList(SkTagList*); michael@0: void removeTagList(U8CPU tag); michael@0: michael@0: private: michael@0: SkEventSinkID fID; michael@0: SkTagList* fTagHead; michael@0: michael@0: // for our private link-list michael@0: SkEventSink* fNextSink; michael@0: michael@0: typedef SkRefCnt INHERITED; michael@0: }; michael@0: michael@0: #endif