| 1 | /* | 
|---|
| 2 | *   ORXONOX - the hottest 3D action shooter ever to exist | 
|---|
| 3 | *                    > www.orxonox.net < | 
|---|
| 4 | * | 
|---|
| 5 | * | 
|---|
| 6 | *   License notice: | 
|---|
| 7 | * | 
|---|
| 8 | *   This program is free software; you can redistribute it and/or | 
|---|
| 9 | *   modify it under the terms of the GNU General Public License | 
|---|
| 10 | *   as published by the Free Software Foundation; either version 2 | 
|---|
| 11 | *   of the License, or (at your option) any later version. | 
|---|
| 12 | * | 
|---|
| 13 | *   This program is distributed in the hope that it will be useful, | 
|---|
| 14 | *   but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 15 | *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 16 | *   GNU General Public License for more details. | 
|---|
| 17 | * | 
|---|
| 18 | *   You should have received a copy of the GNU General Public License | 
|---|
| 19 | *   along with this program; if not, write to the Free Software | 
|---|
| 20 | *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
|---|
| 21 | * | 
|---|
| 22 | *   Author: | 
|---|
| 23 | *      Reto Grieder | 
|---|
| 24 | *   Co-authors: | 
|---|
| 25 | *      ... | 
|---|
| 26 | * | 
|---|
| 27 | */ | 
|---|
| 28 |  | 
|---|
| 29 | /** | 
|---|
| 30 | @file | 
|---|
| 31 | @brief Declaration of the OrxonoxOverlay class. | 
|---|
| 32 | */ | 
|---|
| 33 |  | 
|---|
| 34 | #ifndef _OrxonoxOverlay_H__ | 
|---|
| 35 | #define _OrxonoxOverlay_H__ | 
|---|
| 36 |  | 
|---|
| 37 | #include "OrxonoxPrereqs.h" | 
|---|
| 38 |  | 
|---|
| 39 | #include <string> | 
|---|
| 40 |  | 
|---|
| 41 | #include "util/Math.h" | 
|---|
| 42 | #include "util/OgreForwardRefs.h" | 
|---|
| 43 | #include "core/BaseObject.h" | 
|---|
| 44 | #include "core/WindowEventListener.h" | 
|---|
| 45 |  | 
|---|
| 46 | namespace orxonox | 
|---|
| 47 | { | 
|---|
| 48 | /** | 
|---|
| 49 | @brief | 
|---|
| 50 | Base class to display content directly onto the screen. | 
|---|
| 51 | This is merely a wrapper of the Ogre::Overlay to implement more features and integrate it | 
|---|
| 52 | in our class hierarchy for xml loading and config values. | 
|---|
| 53 | The mentioned features are: | 
|---|
| 54 | - Automatic positioning depending on the scale and the rotation angle. | 
|---|
| 55 | You can specify a "pick point" relative to the overlay itself. This point will always be exactly | 
|---|
| 56 | at the position (position_) of the overlay. That allows for margin/corner aligment. | 
|---|
| 57 | It even works when a rotation angle is applied. | 
|---|
| 58 | - Virtual methods for changedVisibilty() (BaseObject), angleChanged(), sizeCorrectionChanged(), | 
|---|
| 59 | sizeChanged() and positionChanged(), that can be overridden by any derivative. This enables for | 
|---|
| 60 | custom configurability of the size, position and rotation attributes. For intance, the HUDNavigation | 
|---|
| 61 | should behave differently to sizeChanged() than a standard overlay. | 
|---|
| 62 | - Console commands for scale, rotate and scroll (accessed by name) | 
|---|
| 63 | - Standard Ogre::PanelOverlayElement for a background image (class doesn't have to be derived | 
|---|
| 64 | only for displaying a picture). | 
|---|
| 65 | - Reacts to changes of the window aspect | 
|---|
| 66 | - Last but not least: On demand you can tell the overlay to automatically resale to correct for | 
|---|
| 67 | aspect distortion. E.g. if you play 1024x768 you wouldn't want a round object to be oval. | 
|---|
| 68 | Remark: This can (due to the Ogre::Overlay transformation order) only work for angle that are | 
|---|
| 69 | multiples of 90 degrees. But it's only a small drawback. | 
|---|
| 70 | */ | 
|---|
| 71 | class _OrxonoxExport OrxonoxOverlay : public BaseObject, public WindowEventListener | 
|---|
| 72 | { | 
|---|
| 73 | public: | 
|---|
| 74 | /** | 
|---|
| 75 | @brief | 
|---|
| 76 | Describes the rotational state of a an overlay. | 
|---|
| 77 | Horizontal means 0/180 degrees, Vertical is 90/270 degrees | 
|---|
| 78 | and Inbetween is everything else. | 
|---|
| 79 | */ | 
|---|
| 80 | enum RotationState | 
|---|
| 81 | { | 
|---|
| 82 | Horizontal, | 
|---|
| 83 | Vertical, | 
|---|
| 84 | Inbetween | 
|---|
| 85 | }; | 
|---|
| 86 |  | 
|---|
| 87 | public: | 
|---|
| 88 | OrxonoxOverlay(BaseObject* creator); | 
|---|
| 89 | virtual ~OrxonoxOverlay(); | 
|---|
| 90 |  | 
|---|
| 91 | virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode); | 
|---|
| 92 |  | 
|---|
| 93 | virtual void changedName(); | 
|---|
| 94 |  | 
|---|
| 95 | //! Shows the overlay with an detour to BaseObject::visibility_ | 
|---|
| 96 | void show() { this->setVisible(true); } | 
|---|
| 97 | //! Hides the overlay with an detour to BaseObject::visibility_ | 
|---|
| 98 | void hide() { this->setVisible(false); } | 
|---|
| 99 |  | 
|---|
| 100 | /** Sets whether the aspect of the overlay is corrected. | 
|---|
| 101 | This is for instance useful for round objects that should stay round no matter | 
|---|
| 102 | what the screen resolution is. */ | 
|---|
| 103 | void setAspectCorrection(bool val)        { this->bCorrectAspect_ = val; this->sizeCorrectionChanged(); } | 
|---|
| 104 | //! Returns whether the window aspect is corrected | 
|---|
| 105 | bool getAspectCorrection() const          { return this->bCorrectAspect_; } | 
|---|
| 106 |  | 
|---|
| 107 | //! Sets the position of this overlay on the screen. | 
|---|
| 108 | void setPosition(Vector2 pos)             { this->position_ = pos; this->positionChanged(); } | 
|---|
| 109 |  | 
|---|
| 110 | //! Returns the current position on the screen. | 
|---|
| 111 | const Vector2& getPosition() const        { return this->position_; } | 
|---|
| 112 |  | 
|---|
| 113 | //! Scrolls the overlay. @param offset The offset given. | 
|---|
| 114 | void scroll(const Vector2& offset)        { this->position_ += offset; this->positionChanged(); } | 
|---|
| 115 |  | 
|---|
| 116 | /** Sets the point in the overlay where to pick it when translating. | 
|---|
| 117 | For instance setting it to (1.0,1.0) means that the lower right corner of the | 
|---|
| 118 | overlay will be put at position_. | 
|---|
| 119 | This primarily helps aligning an overlay to any corner/margin on the screen. */ | 
|---|
| 120 | void setPickPoint(const Vector2& position){ this->pickPoint_ = position; this->positionChanged(); } | 
|---|
| 121 |  | 
|---|
| 122 | //! Gets the pick point of this overlay. @see setPickPoint() | 
|---|
| 123 | const Vector2& getPickPoint() const       { return this->pickPoint_; } | 
|---|
| 124 |  | 
|---|
| 125 | //! Sets the rotation angle applied to this overlay in degrees. | 
|---|
| 126 | void setRotation(const Degree& angle)     { this->angle_ = angle; this->angleChanged(); } | 
|---|
| 127 |  | 
|---|
| 128 | //! Gets the rotation angle applied to this overlay in degrees. | 
|---|
| 129 | const Degree& getRotation() const         { return this->angle_; } | 
|---|
| 130 |  | 
|---|
| 131 | //! Rotates the overlay by angle degrees. | 
|---|
| 132 | void rotate(const Degree& angle)          { this->angle_ += angle; this->angleChanged(); } | 
|---|
| 133 |  | 
|---|
| 134 | //! Sets the size of this overlay. | 
|---|
| 135 | void setSize(const Vector2& size)         { this->size_ = size; this->sizeChanged(); } | 
|---|
| 136 |  | 
|---|
| 137 | //! Gets the current size that was set (uncorrected) | 
|---|
| 138 | const Vector2& getSize() const            { return this->size_; } | 
|---|
| 139 |  | 
|---|
| 140 | //! Gets the actual size of the overlay on the screen (corrected) | 
|---|
| 141 | Vector2 getActualSize() const             { return this->size_ * this->sizeCorrection_; } | 
|---|
| 142 |  | 
|---|
| 143 | //! Gets the current size correction (default: 1.0, 1.0) | 
|---|
| 144 | const Vector2& getSizeCorrection() const  { return this->sizeCorrection_; } | 
|---|
| 145 |  | 
|---|
| 146 | //! Scales the overlay by scale. | 
|---|
| 147 | void scale(const Vector2& scale)          { this->size_ *= scale; this->sizeChanged(); } | 
|---|
| 148 |  | 
|---|
| 149 | //! ConsoleCommand: Accesses the overlay by its name and scales it. | 
|---|
| 150 | static void scaleOverlay(const std::string& name, float scale); | 
|---|
| 151 | //! ConsoleCommand: Accesses the overlay by its name and scrolls it. | 
|---|
| 152 | static void scrollOverlay(const std::string& name, const Vector2& scroll); | 
|---|
| 153 | static void toggleVisibility(const std::string& name); | 
|---|
| 154 | //! ConsoleCommand: Accesses the overlay by its name and rotates it. | 
|---|
| 155 | static void rotateOverlay(const std::string& name, const Degree& angle); | 
|---|
| 156 |  | 
|---|
| 157 | void setBackgroundMaterial(const std::string& material); | 
|---|
| 158 | const std::string& getBackgroundMaterial() const; | 
|---|
| 159 |  | 
|---|
| 160 | void setBackgroundAlpha(float alpha); | 
|---|
| 161 |  | 
|---|
| 162 | virtual void changedVisibility(); | 
|---|
| 163 |  | 
|---|
| 164 | inline void setOwner(BaseObject* owner) | 
|---|
| 165 | { | 
|---|
| 166 | if (this->owner_ != owner) | 
|---|
| 167 | { | 
|---|
| 168 | this->owner_ = owner; | 
|---|
| 169 | this->changedOwner(); | 
|---|
| 170 | } | 
|---|
| 171 | } | 
|---|
| 172 | inline BaseObject* getOwner() const | 
|---|
| 173 | { return this->owner_; } | 
|---|
| 174 | virtual void changedOwner() {} | 
|---|
| 175 |  | 
|---|
| 176 | void setOverlayGroup(OverlayGroup* group); | 
|---|
| 177 | inline OverlayGroup* getOverlayGroup() const | 
|---|
| 178 | { return this->group_; } | 
|---|
| 179 | virtual void changedOverlayGroup() | 
|---|
| 180 | { this->changedVisibility(); } | 
|---|
| 181 |  | 
|---|
| 182 | protected: | 
|---|
| 183 | virtual void angleChanged(); | 
|---|
| 184 | virtual void sizeCorrectionChanged(); | 
|---|
| 185 | virtual void sizeChanged(); | 
|---|
| 186 | virtual void positionChanged(); | 
|---|
| 187 |  | 
|---|
| 188 | Ogre::Overlay* overlay_;                   //!< The overlay the entire class is about. | 
|---|
| 189 | Ogre::PanelOverlayElement* background_;    //!< Background image (blank per default). | 
|---|
| 190 |  | 
|---|
| 191 | float windowAspectRatio_;                  //!< Screen.width / screen.height | 
|---|
| 192 | bool bCorrectAspect_;                      //!< Whether or not to correct the size. @see setAspectCorrection() | 
|---|
| 193 | Vector2 size_;                             //!< Internal size of the overlay. | 
|---|
| 194 | Vector2 sizeCorrection_;                   //!< Value to correct the size because of the window aspect. | 
|---|
| 195 | Vector2 position_;                         //!< Position of the pickPoint on the screen. | 
|---|
| 196 | Vector2 pickPoint_;                        //!< Point on the overlay to pick when translating | 
|---|
| 197 | Degree angle_;                             //!< Rotation angle of the overlay | 
|---|
| 198 | RotationState rotState_;                   //!< horizontal, vertical or inbetween | 
|---|
| 199 |  | 
|---|
| 200 | private: | 
|---|
| 201 | void windowResized(unsigned int newWidth, unsigned int newHeight); | 
|---|
| 202 |  | 
|---|
| 203 | static unsigned int hudOverlayCounter_s;   //!< Static counter for hud elements | 
|---|
| 204 | /** Contains all the overlays in a map for quick access via console commands. | 
|---|
| 205 | We could also use the ObjectList, but that doesn't guarantee XMLPort(.) was called and is slower. */ | 
|---|
| 206 | static std::map<std::string, OrxonoxOverlay*> overlays_s; | 
|---|
| 207 | BaseObject* owner_; | 
|---|
| 208 | OverlayGroup* group_; | 
|---|
| 209 | Ogre::Pass* backgroundAlphaPass_; | 
|---|
| 210 | }; | 
|---|
| 211 |  | 
|---|
| 212 | SUPER_FUNCTION(6, OrxonoxOverlay, changedOwner, false); | 
|---|
| 213 | SUPER_FUNCTION(7, OrxonoxOverlay, changedOverlayGroup, false); | 
|---|
| 214 | } | 
|---|
| 215 |  | 
|---|
| 216 | #endif /* _OrxonoxOverlay_H__ */ | 
|---|