//----------------------------------------------------------------------------- // Copyright (c) 2012 GarageGames, LLC // // 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 _GUICONTAINER_H_ #define _GUICONTAINER_H_ #ifndef _GUICONTROL_H_ #include "gui/core/guiControl.h" #endif /// Base class for controls that act as containers to other controls. /// /// @addtogroup gui_container_group Containers /// /// @ingroup gui_group Gui System /// @{ class GuiContainer : public GuiControl { public: typedef GuiControl Parent; enum { updateSelf = BIT(1), updateParent = BIT(2), updateNone = 0 }; protected: S32 mUpdateLayout; ///< Layout Update Mask ControlSizing mSizingOptions; ///< Control Sizing Options S32 mValidDockingMask; public: DECLARE_CONOBJECT(GuiContainer); DECLARE_CATEGORY( "Gui Containers" ); GuiContainer(); virtual ~GuiContainer(); static void initPersistFields(); /// @name Container Sizing /// @{ /// Returns the Mask of valid docking modes supported by this container inline S32 getValidDockingMask() { return mValidDockingMask; }; /// Docking Accessors inline S32 getDocking() { return mSizingOptions.mDocking; }; virtual void setDocking( S32 docking ); /// Docking Protected Field Setter static bool setDockingField( void *object, const char *index, const char *data ) { GuiContainer *pContainer = static_cast(object); pContainer->setUpdateLayout( updateParent ); return true; } inline bool getAnchorTop() const { return mSizingOptions.mAnchorTop; } inline bool getAnchorBottom() const { return mSizingOptions.mAnchorBottom; } inline bool getAnchorLeft() const { return mSizingOptions.mAnchorLeft; } inline bool getAnchorRight() const { return mSizingOptions.mAnchorRight; } inline void setAnchorTop(bool val) { mSizingOptions.mAnchorTop = val; } inline void setAnchorBottom(bool val) { mSizingOptions.mAnchorBottom = val; } inline void setAnchorLeft(bool val) { mSizingOptions.mAnchorLeft = val; } inline void setAnchorRight(bool val) { mSizingOptions.mAnchorRight = val; } ControlSizing getSizingOptions() const { return mSizingOptions; } void setSizingOptions(const ControlSizing& val) { mSizingOptions = val; } /// @} /// @name Sizing Constraints /// @{ virtual const RectI getClientRect(); /// @} /// @name Control Layout Methods /// @{ /// Called when the Layout for a Container needs to be updated because of a resize call or a call to setUpdateLayout /// @param clientRect The Client Rectangle that is available for this Container to layout it's children in virtual bool layoutControls( RectI &clientRect ); /// Set the layout flag to Dirty on a Container, triggering an update to it's layout on the next onPreRender call. /// @attention This can be called without regard to whether the flag is already set, as setting it /// does not actually cause an update, but rather tells the container it should update the next /// chance it gets /// @param updateType A Mask that indicates how the layout should be updated. inline void setUpdateLayout( S32 updateType = updateSelf ) { mUpdateLayout |= updateType; }; /// @} /// @name Container Sizing Methods /// @{ /// Dock a Control with the given docking mode inside the given client rect. /// @attention The clientRect passed in will be modified by the docking of /// the control. It will return the rect that remains after the docking operation. virtual bool dockControl( GuiContainer *control, S32 dockingMode, RectI &clientRect ); /// Update a Controls Anchor based on a delta sizing of it's parents extent /// This function should return true if the control was changed in size or position at all virtual bool anchorControl( GuiControl *control, const Point2I &deltaParentExtent ); /// @} /// @name GuiControl Inherited /// @{ virtual void onChildAdded(GuiControl* control); virtual void onChildRemoved(GuiControl* control); virtual bool resize( const Point2I &newPosition, const Point2I &newExtent ); virtual void childResized(GuiControl *child); virtual void addObject(SimObject *obj); virtual void removeObject(SimObject *obj); virtual bool reOrder(SimObject* obj, SimObject* target); virtual void onPreRender(); /// GuiContainer deals with parentResized calls differently than GuiControl. It will /// update the layout for all of it's non-docked child controls. parentResized calls /// on the child controls will be handled by their default functions, but for our /// purposes we want at least our immediate children to use the anchors that they have /// set on themselves. - JDD [9/20/2006] virtual void parentResized(const RectI &oldParentRect, const RectI &newParentRect); /// @} }; /// @} #endif