#ifndef CONTAINER_H_ #define CONTAINER_H_ #include "Control.h" #include "Layout.h" namespace gameplay { /** * A container is a UI control that can contain other controls. * * The following properties are available for containers: @verbatim container { // Container properties. layout = // A value from the Layout::Type enum. E.g.: LAYOUT_VERTICAL style = // A style from the form's theme. alignment = // Note: 'position' will be ignored. position = // Position of the container on-screen, measured in pixels. autoWidth = autoHeight = size = // Size of the container, measured in pixels. width = // Can be used in place of 'size', e.g. with 'autoHeight = true' height = // Can be used in place of 'size', e.g. with 'autoWidth = true' scroll = // Whether scrolling is allowed and in which directions. scrollBarsAutoHide = // Whether scrollbars fade out when not in use. consumeEvents = // Whether the container propogates input events to the Game's input event handler. Default is true. // All the nested controls within this container. container { ... } label { } textBox { } button { } checkBox { } radioButton { } slider { } } @endverbatim */ class Container : public Control { public: /** * Constant used to auto-hide scrollbars. */ static const int ANIMATE_SCROLLBAR_OPACITY = 8; /** * The definition for container scrolling. */ enum Scroll { SCROLL_NONE = 0, SCROLL_HORIZONTAL = 0x01, SCROLL_VERTICAL = 0x02, SCROLL_BOTH = SCROLL_HORIZONTAL | SCROLL_VERTICAL }; /** * Create a new container. * * @param id The container's ID. * @param style The container's style. * @param layoutType The container's layout type. * * @return The new container. * @script{create} */ static Container* create(const char* id, Theme::Style* style, Layout::Type layoutType = Layout::LAYOUT_ABSOLUTE); /** * Get this container's layout. * * @return This container's layout object. */ Layout* getLayout(); /** * Add a control to this layout. * The control will be assigned the next available index. * * @param control The Control to add. * * @return The index assigned to the added Control. */ unsigned int addControl(Control* control); /** * Insert a control at a specific index. * * @param control The control to add. * @param index The index at which to insert the control. */ void insertControl(Control* control, unsigned int index); /** * Remove a control at a specific index. * * @param index The index from which to remove the control. */ void removeControl(unsigned int index); /** * Remove a control with the given ID. * * @param id The ID of the control to remove. */ void removeControl(const char* id); /** * Remove a specific control. * * @param control The control to remove. */ void removeControl(Control* control); /** * Get the Control at a specific index. * * @param index The index at which to retrieve the Control. * * @return The Control at the given index. */ Control* getControl(unsigned int index) const; /** * Get a Control with a specific ID that belongs to this Layout. * * @param id The ID of the Control to search for. */ Control* getControl(const char* id) const; /** * Get the vector of controls within this container. * * @return The vector of the controls within this container. * @script{ignore} */ const std::vector& getControls() const; /** * Sets the allowed scroll directions for this container. * * @param scroll The allowed scroll directions for this container. */ void setScroll(Scroll scroll); /** * Gets the allowed scroll directions for this container. * * @return The allowed scroll directions for this container. */ Scroll getScroll() const; /** * Set whether scrollbars auto hidden when they become static. * * @param autoHide true to auto hide the scrollbars when they become static. */ void setScrollBarsAutoHide(bool autoHide); /** * Whether scrollbars are always visible, or only visible while scrolling. * * @return Whether scrollbars are always visible. */ bool isScrollBarsAutoHide() const; /** * Whether this container is currently being scrolled. * * @return Whether this container is currently being scrolled. */ bool isScrolling() const; /** * @see AnimationTarget::getAnimation */ Animation* getAnimation(const char* id = NULL) const; /** * @see Control::isContainer */ bool isContainer() const; /** * @see Control::getType */ const char* getType() const; /** * @see AnimationTarget::getAnimationPropertyComponentCount */ virtual unsigned int getAnimationPropertyComponentCount(int propertyId) const; /** * @see AnimationTarget::getAnimationProperty */ virtual void getAnimationPropertyValue(int propertyId, AnimationValue* value); /** * @see AnimationTarget::setAnimationProperty */ virtual void setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight = 1.0f); protected: /** * Constructor. */ Container(); /** * Destructor. */ virtual ~Container(); /** * Create an empty container. A container's layout type must be specified at creation time. * * @param type The container's layout type. * * @return The new container. */ static Container* create(Layout::Type type); /** * Create a container with a given style and properties, including a list of controls. * * @param style The style to apply to this container. * @param properties The properties to set on this container, including nested controls. * @param theme The theme to search for control styles within. * * @return The new container. */ static Container* create(Theme::Style* style, Properties* properties, Theme* theme); /** * Updates each control within this container, * and positions them according to the container's layout. * * @param container This container's parent container. * @param offset The offset. */ virtual void update(const Control* container, const Vector2& offset); /** * Touch callback on touch events. Controls return true if they consume the touch event. * * @param evt The touch event that occurred. * @param x The x position of the touch in pixels. Left edge is zero. * @param y The y position of the touch in pixels. Top edge is zero. * @param contactIndex The order of occurrence for multiple touch contacts starting at zero. * * @return Whether the touch event was consumed by a control within this container. * * @see Touch::TouchEvent */ virtual bool touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex); /** * Keyboard callback on key events. Passes key events on to the currently focused control. * * @param evt The key event that occurred. * @param key If evt is KEY_PRESS or KEY_RELEASE then key is the key code from Keyboard::Key. * If evt is KEY_CHAR then key is the unicode value of the character. * * @return Whether the key event was consumed by this control. * * @see Keyboard::KeyEvent * @see Keyboard::Key */ virtual bool keyEvent(Keyboard::KeyEvent evt, int key); /** * Mouse callback on mouse events. * * @param evt The mouse event that occurred. * @param x The x position of the mouse in pixels. Left edge is zero. * @param y The y position of the mouse in pixels. Top edge is zero. * @param wheelDelta The number of mouse wheel ticks. Positive is up (forward), negative is down (backward). * * @return True if the mouse event is consumed or false if it is not consumed. * * @see Mouse::MouseEvent */ virtual bool mouseEvent(Mouse::MouseEvent evt, int x, int y, int wheelDelta); /** * Gets a Layout::Type enum from a matching string. * * @param layoutString The layout string to parse */ static Layout::Type getLayoutType(const char* layoutString); /** * Returns whether this container or any of its controls have been modified and require an update. * * @return true if this container or any of its controls have been modified and require an update. */ virtual bool isDirty(); /** * Adds controls nested within a properties object to this container, * searching for styles within the given theme. * * @param theme The them to add controls from * @param properties The properties to use. */ void addControls(Theme* theme, Properties* properties); /** * Draws a sprite batch for the specified clipping rect . * * @param spriteBatch The sprite batch to use. * @param clip The clipping rectangle. * @param needsClear Whether it needs to be cleared. * @param cleared Whether it was previously cleared * @param targetHeight The targets height */ virtual void draw(SpriteBatch* spriteBatch, const Rectangle& clip, bool needsClear, bool cleared, float targetHeight); /** * Update scroll position and velocity. */ void updateScroll(); /** * Applies touch events to scroll state. * * @param evt The touch event that occurred. * @param x The x position of the touch in pixels. Left edge is zero. * @param y The y position of the touch in pixels. Top edge is zero. * @param contactIndex The order of occurrence for multiple touch contacts starting at zero. * * @return Whether the touch event was consumed by scrolling within this container. * * @see Touch::TouchEvent */ bool touchEventScroll(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex); /** * Mouse scroll event callback. * * @param evt The mouse scroll event that occurred. * @param x The x position of the scroll in pixels. Left edge is zero. * @param y The y position of the scroll in pixels. Top edge is zero. * @param wheelDelta The value change of the mouse's scroll wheel. * * @return Whether the scroll event was consumed by scrolling within this container. * * @see Mouse::MouseEvent */ bool mouseEventScroll(Mouse::MouseEvent evt, int x, int y, int wheelDelta); /** * Mouse pointer event callback. * * @param mouse Whether to treat the event as a mouse event or a touch event. * @param evt The pointer event (either a Mouse::MouseEvent or a Touch::TouchEvent). * @param x The x position of the pointer event in pixels. Left edge is zero. * @param y The y position of the pointer event in pixels. Top edge is zero. * @param data The event's data (depends on whether it is a mouse event or a touch event). * * @return Whether the pointer event was consumed by this container. * * @see Mouse::MouseEvent * @see Touch::TouchEvent */ bool pointerEvent(bool mouse, char evt, int x, int y, int data); /** * Get a Scroll enum from a matching string. * * @param scroll A string representing a Scroll enum. * * @return The Scroll enum value that matches the given string. */ static Scroll getScroll(const char* scroll); /** * The container's layout. */ Layout* _layout; /** * List of controls within the container. */ std::vector _controls; /** * Scrollbar top cap image. */ Theme::ThemeImage* _scrollBarTopCap; /** * Scrollbar vertical image. */ Theme::ThemeImage* _scrollBarVertical; /** * Scrollbar bottom cap image. */ Theme::ThemeImage* _scrollBarBottomCap; /** * Scrollbar left cap image. */ Theme::ThemeImage* _scrollBarLeftCap; /** * Scrollbar horizontal image. */ Theme::ThemeImage* _scrollBarHorizontal; /** * Scrollbar horizontal image. */ Theme::ThemeImage* _scrollBarRightCap; /** * Flag representing whether scrolling is enabled, and in which directions. */ Scroll _scroll; /** * Scroll bar bounds */ Rectangle _scrollBarBounds; /** * How far this layout has been scrolled in each direction. */ Vector2 _scrollPosition; /** * Should the scrollbars auto hide. Default is false. */ bool _scrollBarsAutoHide; /** * Used to animate scrollbars fading out. */ float _scrollBarOpacity; /** * Whether the user is currently touching / holding the mouse down within this layout's container. */ bool _scrolling; /** * First scrolling touch x position */ int _scrollingFirstX; /** * First scrolling touch y position */ int _scrollingFirstY; /** * The last y position when scrolling */ int _scrollingLastX; /** * The last x position when scrolling */ int _scrollingLastY; /** * Time we started scrolling in the x */ double _scrollingStartTimeX; /** * Time we started scrolling in the y */ double _scrollingStartTimeY; /** * The last time we were scrolling */ double _scrollingLastTime; /** * Speed to continue scrolling at after touch release. */ Vector2 _scrollingVelocity; /** * Friction dampens velocity. */ float _scrollingFriction; /** * Are we scrolling to the right? */ bool _scrollingRight; /** * Are we scrolling down? */ bool _scrollingDown; /** * Locked to scrolling vertically by grabbing the scrollbar with the mouse. */ bool _scrollingMouseVertically; /** * Locked to scrolling horizontally by grabbing the scrollbar with the mouse. */ bool _scrollingMouseHorizontally; private: /** * Constructor. */ Container(const Container& copy); AnimationClip* _scrollBarOpacityClip; int _zIndexDefault; int _focusIndexDefault; int _focusIndexMax; float _totalWidth; float _totalHeight; int _contactIndices; bool _initializedWithScroll; }; } #endif