Changes from Version 1 of documentation/C++Manual/Events

Show
Ignore:
Author:
peterc (IP: 192.168.0.1)
Timestamp:
11/19/07 15:13:40 (10 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • documentation/C++Manual/Events

    v0 v1  
     1[[PageOutline(1-5, Contents)]] 
     2= Events = 
     3 
     4Events are sent to elements to indicate actions that have occurred to that element. Rocket generates many events internally (these are fully specified in the [wiki:documentation/RML/Events RML events documentation]). The application can also send arbitrary events to elements. 
     5 
     6When an event is dispatched to an element, it first goes through a ''bubble'' phase where the each of the element's ancestors has an opportunity to process the event and stop the propagation. The event is then sent to the target element, then goes through a ''capture'' phase where it falls back to its root ancestor. 
     7 
     8Events are identified by a descriptive string name (such as "keydown", "blur", etc) and a dictionary of parameters that further describe the event. For example, the "keydown" event has parameters for identifying the actual key that was pressed and the state of the key modifiers. 
     9 
     10Events can be handled internally by the elements they are sent to or by an event listener object. An event listener is able to subscribe to specific events on an element and will be notified whenever those events occur. 
     11 
     12== Event interface == 
     13 
     14An event is represented by the Rocket::Core::Event structure, defined in Rocket/Core/Event.h. The public interface to an event object is: 
     15 
     16{{{ 
     17class Event 
     18{ 
     19public: 
     20        enum EventPhase { PHASE_UNKNOWN, PHASE_CAPTURE, PHASE_TARGET, PHASE_BUBBLE }; 
     21 
     22        // Get the current propagation phase. 
     23        // @return Current phase the event is in. 
     24        Rocket::Core::Event::EventPhase GetPhase() const; 
     25 
     26        // Get the current element in the propagation. 
     27        // @return The current element in propagation. 
     28        Rocket::Core::Element* GetCurrentElement() const; 
     29 
     30        // Get the target element. 
     31        // @return The target element of this event. 
     32        Rocket::Core::Element* GetTargetElement() const; 
     33 
     34        // Get the event type. 
     35        // @return The event type. 
     36        const EMP::Core::String& GetType() const; 
     37 
     38        // Returns the value of one of the event's parameters. 
     39        // @param key[in] The name of the desired parameter. 
     40        // @return The value of the requested parameter. 
     41        template < typename T > 
     42        T GetParameter(const EMP::Core::String& key, const T& default_value); 
     43 
     44        // Stops the propagation of the event. 
     45        void StopPropagation(); 
     46}; 
     47}}} 
     48 
     49The ''phase'' of the event, returned by GetPhase(), will be PHASE_CAPTURE if the event listener received the event during the capture phase or PHASE_BUBBLE if during the bubbling phase. 
     50 
     51The ''target element'', returned by GetTargetElement(), is the element the event was originally sent to. The ''current element'', returned by GetCurrentElement(), is the element the event is currently being sent to. This may be the target element or one of the target element's ancestors. 
     52 
     53The name of the event ("keydown", "focus", etc) is returned from GetType(). You can also use the equality operator to compare an event directly with a string. 
     54 
     55You can fetch the parameters of the event with the templated GetParameter() function. The exact parameters of each event are detailed in the [wiki:documentation/RML/Events event documentation]. 
     56 
     57For event types that can be interrupted, a listener can call the StopPropagation() function on an event to prevent the event's progress through the event cycle. 
     58 
     59== Event listeners == 
     60 
     61Any object that wants to listen for events derives from Rocket::Core::EventListener, and implements the one required pure virtual function: 
     62 
     63{{{ 
     64// Process the incoming event. 
     65virtual void ProcessEvent(Rocket::Core::Event& event) = 0; 
     66}}} 
     67 
     68The ProcessEvent() function will be called every time a relevant event is sent to an element the listener is subscribed to. 
     69 
     70=== Attaching to an element === 
     71 
     72To subscribe an event listener to an element, call the AddEventListener() function on the element to attach to. 
     73 
     74{{{ 
     75// Adds an event listener to this element. 
     76// @param[in] event Event to attach to. 
     77// @param[in] listener The listener object to be attached. 
     78// @param[in] in_capture_phase True to attach in the capture phase, false in bubble phase. 
     79void AddEventListener(const EMP::Core::String& event, 
     80                      Rocket::Core::EventListener* listener, 
     81                      bool in_capture_phase = false); 
     82}}} 
     83 
     84The function takes the following parameters: 
     85 * ''event'': The string name of the event the listener wants to attach to, for example "keydown", "focus", etc. 
     86 * ''listener'': The event listener object to attach. 
     87 * ''in_capture_phase'': If true, the event listener will receive the event in the capture phase, otherwise, in the bubbling phase. See the [[wiki:documentation/RML/Events RML event documentation] for more information. 
     88 
     89=== Detaching from an element === 
     90 
     91To unsubscribe an event listener from an element, call the RemoveEventListener() function on the element: 
     92 
     93{{{ 
     94// Removes an event listener from this element. 
     95// @param[in] event Event to detach from. 
     96// @param[in] listener The listener object to be detached. 
     97// @param[in] in_capture_phase True to detach from the capture phase, false from the bubble phase. 
     98void RemoveEventListener(const EMP::Core::String& event, 
     99                         Rocket::Core::EventListener* listener, 
     100                         bool in_capture_phase = false); 
     101}}} 
     102 
     103== Sending events == 
     104 
     105The application can send an arbitrary event to an element through the DispatchEvent() function on Rocket::Core::Element. 
     106 
     107{{{ 
     108// Sends an event to this element. 
     109// @param[in] event Name of the event in string form. 
     110// @param[in] parameters The event parameters. 
     111// @param[in] interruptible True if the propagation of the event be stopped. 
     112void DispatchEvent(const EMP::Core::String& event, 
     113                   const EMP::Core::Dictionary& parameters, 
     114                   bool interruptible = false); 
     115}}} 
     116 
     117The event will be created and sent through the standard event loop. The following example sends a "close" event to an element: 
     118 
     119{{{ 
     120EMP::Core::Dictionary parameters; 
     121parameters.Set("source", "user"); 
     122 
     123element->DispatchEvent("close", parameters); 
     124}}} 
     125 
     126== Custom events == 
     127 
     128Events are instanced through an event instancer similarly to contexts. The instancer can be overridden with a custom instancer if a custom event is required; this is generally only needed to integrate a scripting language into Rocket. 
     129 
     130A custom event inherits from Rocket::Core::Event. There are no virtual functions to be overridden. 
     131 
     132=== Creating a custom event instancer === 
     133 
     134A custom event instancer needs to be created and registered with the Rocket factory in order to have custom events instanced. A custom event instancer derives from Rocket::Core::EventInstancer and implements the required pure virtual functions: 
     135 
     136{{{ 
     137// Instance an event object. 
     138// @param[in] target Target element of this event. 
     139// @param[in] name Name of this event. 
     140// @param[in] parameters Additional parameters for this event. 
     141// @param[in] interruptible If the event propagation can be stopped. 
     142virtual Rocket::Core::Event* InstanceEvent(Rocket::Core::Element* target, 
     143                                           const EMP::Core::String& name, 
     144                                           const EMP::Core::Dictionary& parameters, 
     145                                           bool interruptible) = 0; 
     146 
     147// Releases an event instanced by this instancer. 
     148// @param[in] event The event to release. 
     149virtual void ReleaseEvent(Event* event) = 0; 
     150 
     151// Releases this event instancer. 
     152virtual void Release() = 0; 
     153}}} 
     154 
     155InstanceEvent() will be called whenever the factory is called upon to instance an event. The parameters to the function are: 
     156 
     157 * ''target'': The element the event is begin targeted at. 
     158 * ''name'': The name of the event ("keydown", "focus", etc). 
     159 * ''parameters'': The parameters to the event as a dictionary. 
     160 * ''interruptible'': True if the event can be interrupted (ie, prevented from propagating throughout the entire event cycle), false if not. 
     161 
     162If InstanceEvent() is successful, return the new event. Otherwise, return NULL (0) to indicate an instancing error. 
     163 
     164ReleaseEvent() will be called when an event instanced through the instancer is no longer required by the system. It should be deleted appropriately. 
     165 
     166Release() will be called when the event instancer is no longer required, usually when Rocket is shut down. The instancer should delete itself as appropriate. 
     167 
     168=== Registering an instancer === 
     169 
     170To register a custom instancer with Rocket, call the RegisterEventInstancer() function on the Rocket factory (Rocket::Core::Factory) after Rocket has been initialised. 
     171 
     172{{{ 
     173// Registers an instancer for all events. 
     174// @param[in] instancer The instancer to be called. 
     175// @return The registered instanced on success, NULL on failure. 
     176static Rocket::Core::EventInstancer* RegisterEventInstancer(Rocket::Core::EventInstancer* instancer); 
     177}}} 
     178 
     179Like other instancers, the event instancer is reference counted. Remember to remove the initial reference after you register a custom instancer with the factory. 
     180 
     181== Inline events == 
     182 
     183Event responses can be specified as element attributes inside RML, similarly to HTML. For example, in the following RML fragment a response is given to the "click" event. 
     184 
     185{{{ 
     186<rml> 
     187        <head> 
     188        </head> 
     189        <body> 
     190                <button onclick="game.start()">Start Game</button> 
     191... 
     192}}} 
     193 
     194Notice the "on" prefix before the event name of "click". All event bindings from RML are prefixed this way. 
     195 
     196Rocket sends inline events to event listener proxy objects that are created by the application. An application must therefore register a custom event listener instancer to have an opportunity to interpret the events. 
     197 
     198=== Creating a custom event listener instancer === 
     199 
     200A custom event listener instancer derives from Rocket::Core::EventListenerInstancer. The following pure virtual functions must be implemented: 
     201 
     202{{{ 
     203// Instance an event listener object. 
     204// @param value Value of the event. 
     205virtual Rocket::Core::EventListener* InstanceEventListener(const EMP::Core::String& value) = 0; 
     206 
     207// Releases this event listener instancer. 
     208virtual void Release() = 0; 
     209}}} 
     210 
     211InstanceEventListener() will be called during RML parsing whenever the factory needs to find an event listener for an inline event. The parameter ''value'' will be the raw event response string as specified in the RML. 
     212 
     213Release() will be called when the event instancer is no longer required, usually when Rocket is shut down. The instancer should delete itself as appropriate.