| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341 |
- /*
- * This source file is part of libRocket, the HTML/CSS Interface Middleware
- *
- * For the latest information, see http://www.librocket.com
- *
- * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- */
- #ifndef ROCKETCORECONTEXT_H
- #define ROCKETCORECONTEXT_H
- #include "Header.h"
- #include "Types.h"
- #include "ReferenceCountable.h"
- #include "ElementReference.h"
- #include "Input.h"
- #include "String.h"
- #include "ScriptInterface.h"
- namespace Rocket {
- namespace Core {
- class Stream;
- class Dictionary;
- }
- }
- namespace Rocket {
- namespace Core {
- class ContextInstancer;
- class ElementDocument;
- class EventListener;
- class RenderInterface;
- /**
- A context for storing, rendering and processing RML documents. Multiple contexts can exist simultaneously.
- @author Peter Curry
- */
- class ROCKETCORE_API Context : public ScriptInterface
- {
- public:
- /// Constructs a new, uninitialised context. This should not be called directly, use Core::CreateContext()
- /// instead.
- /// @param[in] name The name of the context.
- Context(const String& name);
- /// Destroys a context.
- virtual ~Context();
- /// Returns the name of the context.
- /// @return The context's name.
- const String& GetName() const;
- /// Changes the dimensions of the context.
- /// @param[in] dimensions The new dimensions of the context.
- void SetDimensions(const Vector2i& dimensions);
- /// Returns the dimensions of the context.
- /// @return The current dimensions of the context.
- const Vector2i& GetDimensions() const;
- /// Updates all elements in the context's documents.
- bool Update();
- /// Renders all visible elements in the context's documents.
- bool Render();
- /// Creates a new, empty document and places it into this context.
- /// @param[in] tag The document type to create.
- /// @return The new document, or NULL if no document could be created. The document is returned with a reference owned by the caller.
- ElementDocument* CreateDocument(const String& tag = "body");
- /// Load a document into the context.
- /// @param[in] document_path The path to the document to load.
- /// @return The loaded document, or NULL if no document was loaded. The document is returned with a reference owned by the caller.
- ElementDocument* LoadDocument(const String& document_path);
- /// Load a document into the context.
- /// @param[in] document_stream The opened stream, ready to read.
- /// @return The loaded document, or NULL if no document was loaded. The document is returned with a reference owned by the caller.
- ElementDocument* LoadDocument(Stream* document_stream);
- /// Load a document into the context.
- /// @param[in] string The string containing the document RML.
- /// @return The loaded document, or NULL if no document was loaded. The document is returned with a reference owned by the caller.
- ElementDocument* LoadDocumentFromMemory(const String& string);
- /// Unload the given document.
- /// @param[in] document The document to unload.
- void UnloadDocument(ElementDocument* document);
- /// Unloads all loaded documents.
- void UnloadAllDocuments();
- /// Adds a previously-loaded cursor document as a mouse cursor within this context. This allows you to share
- /// cursors between contexts.
- /// @param[in] cursor_document The document to add as a cursor into this context.
- void AddMouseCursor(ElementDocument* cursor_document);
- /// Loads a document as a mouse cursor within this context.
- /// @param[in] cursor_document_path The path to the document to load as a cursor.
- /// @return The loaded cursor document, or NULL if no document was loaded. The document is returned with a reference owned by the caller.
- ElementDocument* LoadMouseCursor(const String& cursor_document_path);
- /// Unload the given cursor.
- /// @param[in] cursor_name The name of cursor to unload.
- void UnloadMouseCursor(const String& cursor_name);
- /// Unloads all currently loaded cursors.
- void UnloadAllMouseCursors();
- /// Sets a cursor as the active cursor.
- /// @param[in] cursor_name The name of the cursor to activate.
- /// @return True if a cursor exists with the given name, false if not.
- bool SetMouseCursor(const String& cursor_name);
- /// Shows or hides the cursor.
- /// @param[in] show True to show the cursor, false to hide it.
- void ShowMouseCursor(bool show);
- /// Returns the first document in the context with the given id.
- /// @param[in] id The id of the desired document.
- /// @return The document (if it was found), or NULL if no document exists with the ID. The document is returned with a borrowed reference.
- ElementDocument* GetDocument(const String& id);
- /// Returns a document in the context by index.
- /// @param[in] index The index of the desired document.
- /// @return The document (if one exists with this index), or NULL if the index was invalid. The document is returned with a borrowed reference.
- ElementDocument* GetDocument(int index);
- /// Returns the number of documents in the context.
- /// @return The number of documents in the context.
- int GetNumDocuments() const;
- /// Returns the hover element.
- /// @return The element the mouse cursor is hovering over. The element is returned with a borrowed reference.
- Element* GetHoverElement();
- /// Returns the focus element.
- /// @return The element with input focus. The element is returned with a borrowed reference.
- Element* GetFocusElement();
- /// Returns the root element that holds all the documents
- /// @return The root element. The element is returned with a borrowed reference.
- Element* GetRootElement();
- /// Brings the document to the front of the document stack.
- /// @param[in] document The document to pull to the front of the stack.
- void PullDocumentToFront(ElementDocument* document);
- /// Sends the document to the back of the document stack.
- /// @param[in] document The document to push to the bottom of the stack.
- void PushDocumentToBack(ElementDocument* document);
- /// Adds an event listener to the context's root element.
- /// @param[in] event The name of the event to attach to.
- /// @param[in] listener Listener object to be attached.
- /// @param[in] in_capture_phase True if the listener is to be attached to the capture phase, false for the bubble phase.
- void AddEventListener(const String& event, EventListener* listener, bool in_capture_phase = false);
- /// Removes an event listener from the context's root element.
- /// @param[in] event The name of the event to detach from.
- /// @param[in] listener Listener object to be detached.
- /// @param[in] in_capture_phase True to detach from the capture phase, false from the bubble phase.
- void RemoveEventListener(const String& event, EventListener* listener, bool in_capture_phase = false);
- /// Sends a key down event into this context.
- /// @param[in] key_identifier The key pressed.
- /// @param[in] key_modifier_state The state of key modifiers (shift, control, caps-lock, etc) keys; this should be generated by ORing together members of the Input::KeyModifier enumeration.
- /// @return True if the event was not consumed (ie, was prevented from propagating by an element), false if it was.
- bool ProcessKeyDown(Input::KeyIdentifier key_identifier, int key_modifier_state);
- /// Sends a key up event into this context.
- /// @param[in] key_identifier The key released.
- /// @param[in] key_modifier_state The state of key modifiers (shift, control, caps-lock, etc) keys; this should be generated by ORing together members of the Input::KeyModifier enumeration.
- /// @return True if the event was not consumed (ie, was prevented from propagating by an element), false if it was.
- bool ProcessKeyUp(Input::KeyIdentifier key_identifier, int key_modifier_state);
- /// Sends a single character of text as text input into this context.
- /// @param[in] character The UCS-2 character to send into this context.
- /// @return True if the event was not consumed (ie, was prevented from propagating by an element), false if it was.
- bool ProcessTextInput(word character);
- /// Sends a string of text as text input into this context.
- /// @param[in] string The UCS-2 string to send into this context.
- /// @return True if the event was not consumed (ie, was prevented from propagating by an element), false if it was.
- bool ProcessTextInput(const String& string);
- /// Sends a mouse movement event into this context.
- /// @param[in] x The x-coordinate of the mouse cursor, in window-coordinates (ie, 0 should be the left of the client area).
- /// @param[in] y The y-coordinate of the mouse cursor, in window-coordinates (ie, 0 should be the top of the client area).
- /// @param[in] key_modifier_state The state of key modifiers (shift, control, caps-lock, etc) keys; this should be generated by ORing together members of the Input::KeyModifier enumeration.
- void ProcessMouseMove(int x, int y, int key_modifier_state);
- /// Sends a mouse-button down event into this context.
- /// @param[in] button_index The index of the button that was pressed; 0 for the left button, 1 for right, and any others from 2 onwards.
- /// @param[in] key_modifier_state The state of key modifiers (shift, control, caps-lock, etc) keys; this should be generated by ORing together members of the Input::KeyModifier enumeration.
- void ProcessMouseButtonDown(int button_index, int key_modifier_state);
- /// Sends a mouse-button up event into this context.
- /// @param[in] button_index The index of the button that was release; 0 for the left button, 1 for right, and any others from 2 onwards.
- /// @param[in] key_modifier_state The state of key modifiers (shift, control, caps-lock, etc) keys; this should be generated by ORing together members of the Input::KeyModifier enumeration.
- void ProcessMouseButtonUp(int button_index, int key_modifier_state);
- /// Sends a mouse-wheel movement event into this context.
- /// @param[in] wheel_delta The mouse-wheel movement this frame. Rocket treats a negative delta as up movement (away from the user), positive as down.
- /// @param[in] key_modifier_state The state of key modifiers (shift, control, caps-lock, etc) keys; this should be generated by ORing together members of the Input::KeyModifier enumeration.
- /// @return True if the event was not consumed (ie, was prevented from propagating by an element), false if it was.
- bool ProcessMouseWheel(int wheel_delta, int key_modifier_state);
- /// Gets the context's render interface.
- /// @return The render interface the context renders through.
- RenderInterface* GetRenderInterface() const;
- /// Gets the current clipping region for the render traversal
- /// @param[out] origin The clipping origin
- /// @param[out] dimensions The clipping dimensions
- bool GetActiveClipRegion(Vector2i& origin, Vector2i& dimensions) const;
- /// Sets the current clipping region for the render traversal
- /// @param[out] origin The clipping origin
- /// @param[out] dimensions The clipping dimensions
- void SetActiveClipRegion(const Vector2i& origin, const Vector2i& dimensions);
- /// Sets the instancer to use for releasing this object.
- /// @param[in] instancer The context's instancer.
- void SetInstancer(ContextInstancer* instancer);
- protected:
- virtual void OnReferenceDeactivate();
- private:
- String name;
- Vector2i dimensions;
- ContextInstancer* instancer;
- typedef std::set< ElementReference > ElementSet;
- typedef std::vector< ElementReference > ElementList;
- // Set of elements that are currently in hover state.
- ElementSet hover_chain;
- // List of elements that are currently in active state.
- ElementList active_chain;
- // History of windows that have had focus
- ElementList document_focus_history;
- // Documents that have been unloaded from the context but not yet released.
- ElementList unloaded_documents;
- // Root of the element tree.
- Element* root;
- // The element that current has input focus.
- ElementReference focus;
- // The top-most element being hovered over.
- ElementReference hover;
- // The element that was being hovered over when the primary mouse button was pressed most recently.
- ElementReference active;
- // The element that was clicked on last.
- Element* last_click_element;
- // The time the last click occured.
- float last_click_time;
- typedef std::map< String, ElementDocument* > CursorMap;
- CursorMap cursors;
- ElementReference default_cursor;
- ElementReference active_cursor;
- bool show_cursor;
- ElementDocument* cursor_proxy;
- // The element that is currently being dragged (or about to be dragged).
- ElementReference drag;
- // True if a drag has begun (ie, the ondragstart event has been fired for the drag element), false otherwise.
- bool drag_started;
- // True if the current drag is a verbose drag (ie, sends ondragover, ondragout, ondragdrop, etc, events).
- bool drag_verbose;
- // Used when dragging a cloned object.
- Element* drag_clone;
- // The element currently being dragged over; this is equivalent to hover, but only set while an element is being
- // dragged, and excludes the dragged element.
- ElementReference drag_hover;
- // Set of elements that are currently being dragged over; this differs from the hover state as the dragged element
- // itself can't be part of it.
- ElementSet drag_hover_chain;
- // Input state; stored from the most recent input events we receive from the application.
- Vector2i mouse_position;
- // The render interface this context renders through.
- RenderInterface* render_interface;
- Vector2i clip_origin;
- Vector2i clip_dimensions;
- // Internal callback for when an element is removed from the hierarchy.
- void OnElementRemove(Element* element);
- // Internal callback for when a new element gains focus.
- bool OnFocusChange(Element* element);
- // Generates an event for faking clicks on an element.
- void GenerateClickEvent(Element* element);
- // Updates the current hover elements, sending required events.
- void UpdateHoverChain(const Dictionary& parameters, const Dictionary& drag_parameters, const Vector2i& old_mouse_position);
- // Returns the youngest descendent of the given element which is under the given point in screen coordinates.
- // @param[in] point The point to test.
- // @param[in] ignore_element If set, this element and its descendents will be ignored.
- // @param[in] element Used internally.
- // @return The element under the point, or NULL if nothing is.
- Element* GetElementAtPoint(const Vector2f& point, const Element* ignore_element = NULL, Element* element = NULL);
- // Creates the drag clone from the given element. The old drag clone will be released if
- // necessary.
- // @param[in] element The element to clone.
- void CreateDragClone(Element* element);
- // Releases the drag clone, if one exists.
- void ReleaseDragClone();
- // Builds the parameters for a generic key event.
- void GenerateKeyEventParameters(Dictionary& parameters, Input::KeyIdentifier key_identifier);
- // Builds the parameters for a generic mouse event.
- void GenerateMouseEventParameters(Dictionary& parameters, int button_index = -1);
- // Builds the parameters for the key modifier state.
- void GenerateKeyModifierEventParameters(Dictionary& parameters, int key_modifier_state);
- // Builds the parameters for a drag event.
- void GenerateDragEventParameters(Dictionary& parameters);
- // Releases all unloaded documents pending destruction.
- void ReleaseUnloadedDocuments();
- // Sends the specified event to all elements in new_items that don't appear in old_items.
- static void SendEvents(const ElementSet& old_items, const ElementSet& new_items, const String& event, const Dictionary& parameters, bool interruptible);
- friend class Element;
- friend ROCKETCORE_API Context* CreateContext(const String&, const Vector2i&, RenderInterface*);
- };
- }
- }
- #endif
|