1 /* 2 * This file is part of Dune Legacy. 3 * 4 * Dune Legacy is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * Dune Legacy is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with Dune Legacy. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef WINDOW_H 19 #define WINDOW_H 20 21 #include "Widget.h" 22 23 24 #include <iostream> 25 #include <queue> 26 27 #include <SDL.h> 28 29 /// A class representing a window 30 class Window : public Widget { 31 public: 32 /** 33 Constructor for creating a window 34 \param x x position of this window 35 \param y y position of this window 36 \param w width of this window 37 \param h height of this window 38 */ 39 Window(Uint32 x, Uint32 y, Uint32 w, Uint32 h); 40 41 /// destructor 42 virtual ~Window(); 43 44 /** 45 This method is called if a child widget is destroyed (see Widget::~Widget). 46 If pChildWidget is the window widget (See setWindowWidget) then this widget 47 is removed. If pChildWidget is the child window then the child window is closed. 48 \param pChildWidget widget to remove 49 */ removeChildWidget(Widget * pChildWidget)50 virtual void removeChildWidget(Widget* pChildWidget) { 51 if(pChildWidget == pWindowWidget) { 52 pWindowWidget = nullptr; 53 } else if(pChildWidget == pChildWindow) { 54 pChildWindow = nullptr; 55 } 56 } 57 58 /** 59 Opens a child window. The new window is drawn above this window. 60 \param pChildWindow new window 61 */ 62 virtual void openWindow(Window* pChildWindow); 63 64 /** 65 Closes the child window. 66 */ 67 virtual void closeChildWindow(); 68 69 /** 70 This method is called, when the child window is about to be closed. 71 This child window will be closed after this method returns. 72 \param pChildWindow The child window that will be closed 73 */ onChildWindowClose(Window * pChildWindow)74 virtual void onChildWindowClose(Window* pChildWindow) { ; }; 75 76 77 /** 78 This method checks whether this window has a child window. 79 \return true if child window present, false otherwise 80 */ hasChildWindow()81 bool hasChildWindow() const { return (pChildWindow != nullptr); }; 82 83 /** 84 Get the current position of this window. 85 \return current position of this window 86 */ getPosition()87 inline const Point& getPosition() { return position; }; 88 89 /** 90 Sets the current window position and size. 91 \param x x position of this window 92 \param y y position of this window 93 \param w width of this window 94 \param h height of this window 95 */ 96 virtual void setCurrentPosition(Uint32 x, Uint32 y, Uint32 w, Uint32 h); 97 98 /** 99 Sets the current window position and size. 100 \param rect position of this window 101 */ setCurrentPosition(const SDL_Rect & rect)102 virtual void setCurrentPosition(const SDL_Rect& rect) { 103 setCurrentPosition(rect.x, rect.y, rect.w, rect.h); 104 } 105 106 /** 107 Handles the input recieved from SDL. Everytime a sdl event occures this method should 108 be called. 109 \param event SDL_Event that occures. 110 */ 111 virtual void handleInput(SDL_Event& event); 112 113 /** 114 Handles a mouse movement. 115 \param x x-coordinate (relative to the left top corner of the window) 116 \param y y-coordinate (relative to the left top corner of the window) 117 \param insideOverlay true, if (x,y) is inside an overlay and this widget may be behind it, false otherwise 118 */ 119 virtual void handleMouseMovement(Sint32 x, Sint32 y, bool insideOverlay = false); 120 121 /** 122 Handles a left mouse click. 123 \param x x-coordinate (relative to the left top corner of the window) 124 \param y y-coordinate (relative to the left top corner of the window) 125 \param pressed true = mouse button pressed, false = mouse button released 126 \return true = click was processed by the window, false = click was not processed by the window 127 */ 128 virtual bool handleMouseLeft(Sint32 x, Sint32 y, bool pressed); 129 130 /** 131 Handles a right mouse click. 132 \param x x-coordinate (relative to the left top corner of the window) 133 \param y y-coordinate (relative to the left top corner of the window) 134 \param pressed true = mouse button pressed, false = mouse button released 135 \return true = click was processed by the window, false = click was not processed by the window 136 */ 137 virtual bool handleMouseRight(Sint32 x, Sint32 y, bool pressed); 138 139 /** 140 Handles mouse wheel scrolling. 141 \param x x-coordinate (relative to the left top corner of the widget) 142 \param y y-coordinate (relative to the left top corner of the widget) 143 \param up true = mouse wheel up, false = mouse wheel down 144 \return true = the mouse wheel scrolling was processed by the widget, false = mouse wheel scrolling was not processed by the widget 145 */ 146 147 virtual bool handleMouseWheel(Sint32 x, Sint32 y, bool up); 148 149 /** 150 Handles a key stroke. 151 \param key the key that was pressed or released. 152 \return true = key stroke was processed by the window, false = key stroke was not processed by the window 153 */ 154 virtual bool handleKeyPress(SDL_KeyboardEvent& key); 155 156 /** 157 Handles a text input event. 158 \param textInput the text input that was performed. 159 \return true = text input was processed by the window, false = text input was not processed by the window 160 */ 161 virtual bool handleTextInput(SDL_TextInputEvent& textInput); 162 163 /** 164 Draws this window to screen. This method should be called every frame. 165 */ draw()166 virtual void draw() { draw(Point(0,0)); }; 167 168 /** 169 Draws this window to screen. This method should be called every frame. 170 \param position Position to draw the window to. The position of the window is added to this. 171 */ 172 virtual void draw(Point position); 173 174 /** 175 This method draws the parts of this window that must be drawn after all the other 176 widgets are drawn (e.g. tooltips). This method is called after draw(). 177 */ drawOverlay()178 virtual void drawOverlay() { drawOverlay(Point(0,0)); }; 179 180 /** 181 This method draws the parts of this window that must be drawn after all the other 182 widgets are drawn (e.g. tooltips). This method is called after draw(). 183 \param Position Position to draw the window to. The position of the window is added to this. 184 */ 185 virtual void drawOverlay(Point position); 186 187 /** 188 That the current window widget. This is typically a container that hold all the widgets in this window. 189 The window itself can contain only one widget. 190 \param pWindowWidget The only widget that this window contains 191 */ setWindowWidget(Widget * pWindowWidget)192 virtual inline void setWindowWidget(Widget* pWindowWidget) { 193 this->pWindowWidget = pWindowWidget; 194 if(this->pWindowWidget != nullptr) { 195 this->pWindowWidget->setParent(this); 196 this->pWindowWidget->resize(getSize().x,getSize().y); 197 this->pWindowWidget->setActive(); 198 } 199 }; 200 201 /** 202 Returns the current window widget. 203 \return the current window widget 204 */ getWindowWidget()205 virtual inline Widget* getWindowWidget() { return pWindowWidget; }; 206 207 /** 208 This method resizes the window. 209 \param newSize the new size of this widget 210 */ resize(Point newSize)211 virtual inline void resize(Point newSize) { 212 resize(newSize.x, newSize.y); 213 }; 214 215 /** 216 This method resizes the window to width and height. 217 \param width the new width of this widget 218 \param height the new height of this widget 219 */ 220 virtual void resize(Uint32 width, Uint32 height); 221 222 /** 223 This method is typically called by the child widget when the child widget 224 requests to resizes its surrounding container. But windows do not resize if 225 it's content changes. 226 */ resizeAll()227 virtual void resizeAll() { 228 // Windows do not get bigger if content changes 229 resize(getSize().x,getSize().y); 230 }; 231 232 /** 233 Set the background of this window. 234 \param pBackground the new background of this window. nullptr=default background 235 \param bFreeBackground should this background be automatically be freed 236 */ 237 virtual void setBackground(SDL_Surface* pBackground, bool bFreeBackground = true); 238 239 /** 240 Set the background of this window. 241 \param pBackground the new background of this window. nullptr=default background 242 \param bFreeBackground should this background be automatically be freed 243 */ 244 virtual void setBackground(SDL_Texture* pBackground, bool bFreeBackground = true); 245 246 /** 247 This method sets a transparent background for this window. 248 \param bTransparent true = the background is transparent, false = the background is not transparent 249 */ 250 virtual void setTransparentBackground(bool bTransparent); 251 252 protected: 253 254 bool processChildWindowOpenCloses(); 255 256 int closeChildWindowCounter; ///< Close the child window after processing all input? 257 Window* pChildWindow; ///< The current child window 258 bool pChildWindowAlreadyClosed; /// Is the child window already closed? 259 std::queue<Window*> queuedChildWindows; ///< We cannot close child windows while they are processed. Queue any newly opened windows here until we close the current child window 260 Widget* pWindowWidget; ///< The current window widget 261 Point position; ///< The left top corner of this window 262 bool bTransparentBackground; ///< true = no background is drawn 263 bool bSelfGeneratedBackground; ///< true = background is created by this window, false = created by someone else 264 bool bFreeBackground; ///< true = background should be automatically be freed 265 SDL_Texture* pBackground; ///< background texture 266 }; 267 268 #endif //WINDOW_H 269