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 MSGBOX_H
19 #define MSGBOX_H
20 
21 #include "Window.h"
22 #include "Button.h"
23 #include "Label.h"
24 #include "Spacer.h"
25 #include "GUIStyle.h"
26 #include "Widget.h"
27 #include "VBox.h"
28 #include "HBox.h"
29 
30 #include <SDL.h>
31 
32 #include <iostream>
33 #include <algorithm>
34 
35 /// A simple class for a message box
36 class MsgBox : public Window {
37 public:
38 
39     /**
40         This method sets a new text for this message box.
41         \param  text The new text for this message box
42     */
setText(const std::string & text)43     virtual inline void setText(const std::string& text) {
44         textLabel.setText(text);
45         resize(std::max(vbox.getMinimumSize().x,120),vbox.getMinimumSize().y);
46     }
47 
48     /**
49         Get the text of this message box.
50         \return the text of this message box
51     */
getText()52     inline const std::string& getText() { return textLabel.getText(); };
53 
54     /**
55         Sets the text color for this message box.
56         \param  textcolor       the color of the text (COLOR_DEFAULT = default color)
57         \param  textshadowcolor the color of the shadow of the text (COLOR_DEFAULT = default color)
58     */
59     virtual inline void setTextColor(Uint32 textcolor, Uint32 textshadowcolor = COLOR_DEFAULT) {
60         textLabel.setTextColor(textcolor, textshadowcolor);
61         okbutton.setTextColor(textcolor, textshadowcolor);
62     }
63 
64     /**
65         This method resizes the message box. This method should only
66         called if the new size is a valid size for this message box (See getMinumumSize).
67         \param  newSize the new size of this progress bar
68     */
resize(Point newSize)69     virtual void resize(Point newSize) {
70         resize(newSize.x,newSize.y);
71     }
72 
73     /**
74         This method resizes the message box to width and height. This method should only be
75         called if the new size is a valid size for this message box (See resizingXAllowed,
76         resizingYAllowed, getMinumumSize).
77         \param  width   the new width of this message box
78         \param  height  the new height of this message box
79     */
resize(Uint32 width,Uint32 height)80     virtual void resize(Uint32 width, Uint32 height) {
81         Window::resize(width,height);
82         position.x = (getRendererWidth() - getSize().x)/2;
83         position.y = (getRendererHeight() - getSize().y)/2;
84     }
85 
86     /**
87         This method is called by the window widget if it requests a resizing of
88         this window.
89     */
resizeAll()90     virtual void resizeAll() {
91         // MsgBox should get bigger if content changes
92         if(pWindowWidget != nullptr) {
93             Point newSize = pWindowWidget->getMinimumSize();
94             newSize.x = std::max(newSize.x,120);
95             newSize.y = std::max(newSize.y,30);
96             resize(newSize.x,newSize.y);
97         }
98     };
99 
100     /**
101         This static method creates a dynamic message box object with Text as the text in the message box.
102         The idea behind this method is to simply create a new message box on the fly and
103         add it as a child window of some other window. If the window gets closed it will be freed.
104         \param  text    The message box text
105         \return The new message box (will be automatically destroyed when it's closed)
106     */
create(const std::string & text)107     static MsgBox* create(const std::string& text) {
108         MsgBox* msgbox = new MsgBox(text);
109         msgbox->pAllocated = true;
110         return msgbox;
111     }
112 
113 protected:
114     /** protected constructor (See create)
115         \param  text    Text of this message box
116     */
MsgBox(const std::string & text)117     explicit MsgBox(const std::string& text)
118      : Window(50,50,50,50) {
119         init(text);
120     }
121 
122     /// destructor
~MsgBox()123     virtual ~MsgBox() {
124     }
125 
126 private:
127     /**
128         Initialization helper method.
129         \param  Text    Text of this message box
130     */
init(const std::string & text)131     void init(const std::string& text) {
132         setWindowWidget(&vbox);
133         vbox.addWidget(VSpacer::create(6));
134         vbox.addWidget(&textLabel);
135         vbox.addWidget(VSpacer::create(3));
136         vbox.addWidget(&hbox);
137         vbox.addWidget(VSpacer::create(6));
138         hbox.addWidget(Spacer::create());
139         hbox.addWidget(&vbox2);
140         vbox2.addWidget(VSpacer::create(4));
141         okbutton.setText("OK");
142         okbutton.setOnClick(std::bind(&MsgBox::onOK, this));
143         vbox2.addWidget(&okbutton);
144         vbox2.addWidget(VSpacer::create(4));
145         hbox.addWidget(Spacer::create());
146         setText(text);
147         textLabel.setAlignment(Alignment_HCenter);
148         okbutton.setActive();
149     }
150 
151     /**
152         This method is called when the OK button is pressed.
153     */
onOK()154     virtual void onOK() {
155         Window* pParentWindow = dynamic_cast<Window*>(getParent());
156         if(pParentWindow != nullptr) {
157             pParentWindow->closeChildWindow();
158         }
159     }
160 
161     VBox vbox;                  ///< vertical box
162     HBox hbox;                  ///< horizontal box
163     VBox vbox2;                 ///< inner vertical box;
164     Label textLabel;            ///< label that contains the text
165     TextButton okbutton;        ///< the ok button
166 };
167 
168 #endif // MSGBOX_H
169