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

Show
Ignore:
Author:
peterc (IP: 192.168.0.1)
Timestamp:
11/16/07 17:35:39 (10 years ago)
Comment:

--

Legend:

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

    v0 v1  
     1[[PageOutline(1-5, Contents)]] 
     2= Contexts = 
     3 
     4Rocket contexts are independent collections of documents. All documents exist within a single context. Contexts are rendered, updated and given input independently of each other at the application's discretion. 
     5 
     6== Uses of multiple contexts == 
     7 
     8Most games will feature a single context for the main interface. Multiple contexts could be used however for a number of different reasons. 
     9 
     10=== Multiple desktops === 
     11 
     12A second or subsequent context could be used to store alternative 'desktops' that the user could switch to, in a similar fashion to many Linux desktops. This could be very useful for interface-heavy games where the user may have several windows open at once, more than could fit easily onto one screen. 
     13 
     14=== In-world interfaces === 
     15 
     16Computer terminals or consoles in a 3D game world could themselves be Rocket contexts. As they wouldn't necessarily be viewed parallel to the screen, mouse input would need to be projected onto the surface. When the context was rendered, it would need to be transformed correctly to fit onto the surface or rendered onto a texture. 
     17 
     18== Creating a context == 
     19 
     20To create a new context, use the CreateContext() function in Rocket::Core. 
     21 
     22{{{ 
     23// Creates a new element context. 
     24// @param[in] name The new name of the context. This must be unique. 
     25// @param[in] dimensions The initial dimensions of the new context. 
     26// @return The new context, or NULL if the context could not be created. 
     27Rocket::Core::Context* CreateContext(const EMP::Core::String& name, 
     28                                     const EMP::Core::Vector2i& dimensions); 
     29}}} 
     30 
     31The context needs a unique string name and initial dimensions. The dimensions are used to generate relative lengths (for example, if a document has a percentage dimension), and sets the extents for the mouse cursor within the context. 
     32 
     33To fetch a previously-constructed context, use the GetContext() function. 
     34 
     35{{{ 
     36// Fetches a previously constructed context by name. 
     37// @param[in] name The name of the desired context. 
     38// @return The desired context, or NULL if no context exists with the given name. 
     39Rocket::Core::Context* GetContext(const EMP::Core::String& name); 
     40}}} 
     41 
     42== Releasing a context == 
     43 
     44Contexts are reference counted, and begin with a reference count of one. Once you have finished with a context, call RemoveReference() to release it. It will be destroyed, and all of its documents released. 
     45 
     46== Update and rendering == 
     47 
     48If a context is active, it should have Update() called on it after the frame's input events have been sent to it. 
     49 
     50{{{ 
     51// Updates all elements in the context's documents. 
     52bool Update(); 
     53}}} 
     54 
     55To render a context, call Render() on it. Easy! 
     56 
     57{{{ 
     58// Renders all visible elements in the context's documents. 
     59bool Render(); 
     60}}} 
     61 
     62== Loading and creating documents == 
     63 
     64Documents are loaded through contexts. To load a document from an RML file into a context, call the LoadDocument() function on the appropriate context. 
     65 
     66{{{ 
     67// Load a document into the context. 
     68// @param[in] document_path The path to the document to load. 
     69// @return The loaded document, or NULL if no document was loaded. 
     70Rocket::Core::ElementDocument* LoadDocument(const EMP::Core::String& document_path); 
     71}}} 
     72 
     73The document_path parameter will be given to Rocket's [wiki:documention/C++Manual/Interfaces#Thefileinterface file interface] to be open and read. If the document is loaded successfully, it will be added to the context and returned. Call Show() on the document to make it visible. 
     74 
     75To create a new, empty document you can populate dynamically, use the CreateDocument() function. 
     76 
     77{{{ 
     78// Creates a new, empty document and places it into this context. 
     79// @param[in] tag The document type to create. 
     80// @return The new document, or NULL if no document could be created. 
     81ElementDocument* CreateDocument(const EMP::Core::String& tag = "document"); 
     82}}} 
     83 
     84The context will attempt to instance an element using the 'body' instancer, with the tag name specified by the caller. If a Rocket::Core::ElementDocument is instanced, it will be added to the context and returned. 
     85 
     86== Cursors == 
     87 
     88Each context maintains a list of cursors that can be used to represent the mouse cursor. Regardless of the number of cursors loaded into a context, only one cursor is rendered at a time. The default cursor is the first element to be loaded; this will be the visible cursor unless an element overrides it through the [wiki:documentation/RCSS/UserInterface#Cursors:thecursorproperty 'cursor' property]. 
     89 
     90=== Loading cursors === 
     91 
     92Mouse cursors can be loaded into a context using the LoadMouseCursor() function. 
     93 
     94{{{ 
     95// Loads a document as a mouse cursor within this context. 
     96// @param[in] cursor_document_path The path to the document to load as a cursor. 
     97// @return The loaded cursor document, or NULL if no document was loaded. 
     98Rocket::Core::ElementDocument* LoadMouseCursor(const EMP::Core::String& cursor_document_path); 
     99}}} 
     100 
     101Cursors are documents themselves, and are loaded the same way internally. Any valid RML document can be loaded as a document; of course, you're most likely to want a simple document with an image decorator, but you're not limited to this! 
     102 
     103Note that the cursor's 'name' is the title of its document. This is the name you'll use to specify it through the 'cursor' property. 
     104 
     105=== Sharing cursors === 
     106 
     107Mouse cursors can also be shared across contexts with the AddMouseCursor() function. 
     108 
     109{{{ 
     110// Adds a previously-loaded cursor document as a mouse cursor within this context. 
     111// @param[in] cursor_document The document to add as a cursor into this context. 
     112void AddMouseCursor(Rocket::Core::ElementDocument* cursor_document); 
     113}}} 
     114 
     115Call AddMouseCursor() with a cursor loaded into another context. 
     116 
     117== Events == 
     118 
     119Event listeners can be attached to a context (rather than an element) to receive events sent to all elements within that context. As with elements, call AddEventListener() to attach a listener and RemoveEventListener() to detach. 
     120 
     121{{{ 
     122// Adds an event listener to the context's root element. 
     123// @param[in] event The name of the event to attach to. 
     124// @param[in] listener Listener object to be attached. 
     125// @param[in] in_capture_phase True if the listener is to be attached to the capture phase, false for the bubble phase. 
     126void AddEventListener(const EMP::Core::String& event, 
     127                      Rocket::Core::EventListener* listener, 
     128                      bool in_capture_phase = false); 
     129 
     130// Removes an event listener from the context's root element. 
     131// @param[in] event The name of the event to detach from. 
     132// @param[in] listener Listener object to be detached. 
     133// @param[in] in_capture_phase True to detach from the capture phase, false from the bubble phase. 
     134void RemoveEventListener(const EMP::Core::String& event, 
     135                         Rocket::Core::EventListener* listener, 
     136                         bool in_capture_phase = false); 
     137}}} 
     138 
     139== Input == 
     140 
     141See the section on [wiki:documentation/C++Manual/Input input] for detail on sending user input from your application into Rocket contexts. 
     142 
     143== Custom contexts == 
     144 
     145Contexts are created, like elements and decorators, through instancers. You can override the default context instancer if you want to create custom contexts. Generally, this is only required for adding support for scripting languages. 
     146 
     147=== Creating a custom context === 
     148 
     149A custom context is a class derived from Rocket::Core::Context. There are no virtual methods on Rocket::Core::Context, so it cannot be specialised. 
     150 
     151=== Creating a custom context instancer === 
     152 
     153A custom context instancer needs to be registered with the Rocket factory in order to override the default instancer. A custom context instancer needs to be derived from Rocket::Core::ContextInstancer, and implement the required virtual methods: 
     154 
     155{{{ 
     156// Instances a context. 
     157// @param[in] name Name of this context. 
     158// @return The instanced context. 
     159virtual Rocket::Core::Context* InstanceContext(const EMP::Core::String& name) = 0; 
     160 
     161// Releases a context previously created by this context. 
     162// @param[in] context The context to release. 
     163virtual void ReleaseContext(Rocket::Core::Context* context) = 0; 
     164 
     165// Releases this context instancer 
     166virtual void Release() = 0; 
     167}}} 
     168 
     169InstanceContext() will be called whenever a new context is requested. It takes a single parameter, ''name'', the name of the new context. If a context can be created, it should be initialised and returned. Otherwise, return NULL (0). 
     170 
     171ReleaseContext() will be called whenever a context is released. The context instancer should destroy the context and free and resources allocated for it. 
     172 
     173Release() will be called when Rocket is shut down. The instancer should delete itself if it was dynamically allocated. 
     174 
     175=== Registering an instancer === 
     176 
     177To register a custom instancer with Rocket, call RegisterContextInstancer() on the Rocket factory after Rocket has been initialised. 
     178 
     179{{{ 
     180Rocket::Core::ContextInstancer* custom_instancer = new CustomContextInstancer(); 
     181Rocket::Core::Factory::RegisterContextInstancer(custom_instancer); 
     182custom_instancer->RemoveReference(); 
     183}}} 
     184 
     185Like other instancers, context instancers are reference counted and begin with a single reference. The factory will add its own reference to the instancer once it is registered, so you must remove the initial reference afterwards.