aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp')
-rw-r--r--libraries/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp463
1 files changed, 463 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp b/libraries/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp
new file mode 100644
index 0000000..57b383d
--- /dev/null
+++ b/libraries/irrlicht-1.8.1/source/Irrlicht/CGUIMessageBox.cpp
@@ -0,0 +1,463 @@
1// Copyright (C) 2002-2012 Nikolaus Gebhardt
2// This file is part of the "Irrlicht Engine".
3// For conditions of distribution and use, see copyright notice in irrlicht.h
4
5#include "CGUIMessageBox.h"
6#ifdef _IRR_COMPILE_WITH_GUI_
7
8#include "IGUISkin.h"
9#include "IGUIEnvironment.h"
10#include "IGUIButton.h"
11#include "IGUIFont.h"
12#include "ITexture.h"
13
14namespace irr
15{
16namespace gui
17{
18
19//! constructor
20CGUIMessageBox::CGUIMessageBox(IGUIEnvironment* environment, const wchar_t* caption,
21 const wchar_t* text, s32 flags,
22 IGUIElement* parent, s32 id, core::rect<s32> rectangle, video::ITexture* image)
23: CGUIWindow(environment, parent, id, rectangle),
24 OkButton(0), CancelButton(0), YesButton(0), NoButton(0), StaticText(0),
25 Icon(0), IconTexture(image),
26 Flags(flags), MessageText(text), Pressed(false)
27{
28 #ifdef _DEBUG
29 setDebugName("CGUIMessageBox");
30 #endif
31
32 // set element type
33 Type = EGUIET_MESSAGE_BOX;
34
35 // remove focus
36 Environment->setFocus(0);
37
38 // remove buttons
39
40 getMaximizeButton()->remove();
41 getMinimizeButton()->remove();
42
43 if (caption)
44 setText(caption);
45
46 Environment->setFocus(this);
47
48 if ( IconTexture )
49 IconTexture->grab();
50
51 refreshControls();
52}
53
54
55//! destructor
56CGUIMessageBox::~CGUIMessageBox()
57{
58 if (StaticText)
59 StaticText->drop();
60
61 if (OkButton)
62 OkButton->drop();
63
64 if (CancelButton)
65 CancelButton->drop();
66
67 if (YesButton)
68 YesButton->drop();
69
70 if (NoButton)
71 NoButton->drop();
72
73 if (Icon)
74 Icon->drop();
75
76 if ( IconTexture )
77 IconTexture->drop();
78}
79
80void CGUIMessageBox::setButton(IGUIButton*& button, bool isAvailable, const core::rect<s32> & btnRect, const wchar_t * text, IGUIElement*& focusMe)
81{
82 // add/remove ok button
83 if (isAvailable)
84 {
85 if (!button)
86 {
87 button = Environment->addButton(btnRect, this);
88 button->setSubElement(true);
89 button->grab();
90 }
91 else
92 button->setRelativePosition(btnRect);
93
94 button->setText(text);
95
96 focusMe = button;
97 }
98 else if (button)
99 {
100 button->drop();
101 button->remove();
102 button =0;
103 }
104}
105
106void CGUIMessageBox::refreshControls()
107{
108 // Layout can be seen as 4 boxes (a layoutmanager would be nice)
109 // One box at top over the whole width for title
110 // Two boxes with same height at the middle beside each other for icon and for text
111 // One box at the bottom for the buttons
112
113 const IGUISkin* skin = Environment->getSkin();
114
115 const s32 buttonHeight = skin->getSize(EGDS_BUTTON_HEIGHT);
116 const s32 buttonWidth = skin->getSize(EGDS_BUTTON_WIDTH);
117 const s32 titleHeight = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH)+2; // titlebar has no own constant
118 const s32 buttonDistance = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
119 const s32 borderWidth = skin->getSize(EGDS_MESSAGE_BOX_GAP_SPACE);
120
121 // add the static text for the message
122 core::rect<s32> staticRect;
123 staticRect.UpperLeftCorner.X = borderWidth;
124 staticRect.UpperLeftCorner.Y = titleHeight + borderWidth;
125 staticRect.LowerRightCorner.X = staticRect.UpperLeftCorner.X + skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH);
126 staticRect.LowerRightCorner.Y = staticRect.UpperLeftCorner.Y + skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT);
127 if (!StaticText)
128 {
129 StaticText = Environment->addStaticText(MessageText.c_str(), staticRect, false, false, this);
130
131 StaticText->setWordWrap(true);
132 StaticText->setSubElement(true);
133 StaticText->grab();
134 }
135 else
136 {
137 StaticText->setRelativePosition(staticRect);
138 StaticText->setText(MessageText.c_str());
139 }
140
141 s32 textHeight = StaticText->getTextHeight();
142 s32 textWidth = StaticText->getTextWidth() + 6; // +6 because the static itself needs that
143 const s32 iconHeight = IconTexture ? IconTexture->getOriginalSize().Height : 0;
144
145 if ( textWidth < skin->getSize(EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH) )
146 textWidth = skin->getSize(EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH) + 6;
147 // no neeed to check for max because it couldn't get larger due to statictextbox.
148 if ( textHeight < skin->getSize(EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT) )
149 textHeight = skin->getSize(EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT);
150 if ( textHeight > skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT) )
151 textHeight = skin->getSize(EGDS_MESSAGE_BOX_MAX_TEXT_HEIGHT);
152
153 // content is text + icons + borders (but not titlebar)
154 s32 contentHeight = textHeight > iconHeight ? textHeight : iconHeight;
155 contentHeight += borderWidth;
156 s32 contentWidth = 0;
157
158 // add icon
159 if ( IconTexture )
160 {
161 core::position2d<s32> iconPos;
162 iconPos.Y = titleHeight + borderWidth;
163 if ( iconHeight < textHeight )
164 iconPos.Y += (textHeight-iconHeight) / 2;
165 iconPos.X = borderWidth;
166
167 if (!Icon)
168 {
169 Icon = Environment->addImage(IconTexture, iconPos, true, this);
170 Icon->setSubElement(true);
171 Icon->grab();
172 }
173 else
174 {
175 core::rect<s32> iconRect( iconPos.X, iconPos.Y, iconPos.X + IconTexture->getOriginalSize().Width, iconPos.Y + IconTexture->getOriginalSize().Height );
176 Icon->setRelativePosition(iconRect);
177 }
178
179 contentWidth += borderWidth + IconTexture->getOriginalSize().Width;
180 }
181 else if ( Icon )
182 {
183 Icon->drop();
184 Icon->remove();
185 Icon = 0;
186 }
187
188 // position text
189 core::rect<s32> textRect;
190 textRect.UpperLeftCorner.X = contentWidth + borderWidth;
191 textRect.UpperLeftCorner.Y = titleHeight + borderWidth;
192 if ( textHeight < iconHeight )
193 textRect.UpperLeftCorner.Y += (iconHeight-textHeight) / 2;
194 textRect.LowerRightCorner.X = textRect.UpperLeftCorner.X + textWidth;
195 textRect.LowerRightCorner.Y = textRect.UpperLeftCorner.Y + textHeight;
196 contentWidth += 2*borderWidth + textWidth;
197 StaticText->setRelativePosition( textRect );
198
199 // find out button size needs
200 s32 countButtons = 0;
201 if (Flags & EMBF_OK)
202 ++countButtons;
203 if (Flags & EMBF_CANCEL)
204 ++countButtons;
205 if (Flags & EMBF_YES)
206 ++countButtons;
207 if (Flags & EMBF_NO)
208 ++countButtons;
209
210 s32 buttonBoxWidth = countButtons * buttonWidth + 2 * borderWidth;
211 if ( countButtons > 1 )
212 buttonBoxWidth += (countButtons-1) * buttonDistance;
213 s32 buttonBoxHeight = buttonHeight + 2 * borderWidth;
214
215 // calc new message box sizes
216 core::rect<s32> tmp = getRelativePosition();
217 s32 msgBoxHeight = titleHeight + contentHeight + buttonBoxHeight;
218 s32 msgBoxWidth = contentWidth > buttonBoxWidth ? contentWidth : buttonBoxWidth;
219
220 // adjust message box position
221 tmp.UpperLeftCorner.Y = (Parent->getAbsolutePosition().getHeight() - msgBoxHeight) / 2;
222 tmp.LowerRightCorner.Y = tmp.UpperLeftCorner.Y + msgBoxHeight;
223 tmp.UpperLeftCorner.X = (Parent->getAbsolutePosition().getWidth() - msgBoxWidth) / 2;
224 tmp.LowerRightCorner.X = tmp.UpperLeftCorner.X + msgBoxWidth;
225 setRelativePosition(tmp);
226
227 // add buttons
228
229 core::rect<s32> btnRect;
230 btnRect.UpperLeftCorner.Y = titleHeight + contentHeight + borderWidth;
231 btnRect.LowerRightCorner.Y = btnRect.UpperLeftCorner.Y + buttonHeight;
232 btnRect.UpperLeftCorner.X = borderWidth;
233 if ( contentWidth > buttonBoxWidth )
234 btnRect.UpperLeftCorner.X += (contentWidth - buttonBoxWidth) / 2; // center buttons
235 btnRect.LowerRightCorner.X = btnRect.UpperLeftCorner.X + buttonWidth;
236
237 IGUIElement* focusMe = 0;
238 setButton(OkButton, (Flags & EMBF_OK) != 0, btnRect, skin->getDefaultText(EGDT_MSG_BOX_OK), focusMe);
239 if ( Flags & EMBF_OK )
240 btnRect += core::position2d<s32>(buttonWidth + buttonDistance, 0);
241 setButton(CancelButton, (Flags & EMBF_CANCEL) != 0, btnRect, skin->getDefaultText(EGDT_MSG_BOX_CANCEL), focusMe);
242 if ( Flags & EMBF_CANCEL )
243 btnRect += core::position2d<s32>(buttonWidth + buttonDistance, 0);
244 setButton(YesButton, (Flags & EMBF_YES) != 0, btnRect, skin->getDefaultText(EGDT_MSG_BOX_YES), focusMe);
245 if ( Flags & EMBF_YES )
246 btnRect += core::position2d<s32>(buttonWidth + buttonDistance, 0);
247 setButton(NoButton, (Flags & EMBF_NO) != 0, btnRect, skin->getDefaultText(EGDT_MSG_BOX_NO), focusMe);
248
249 if (Environment->hasFocus(this) && focusMe)
250 Environment->setFocus(focusMe);
251}
252
253
254//! called if an event happened.
255bool CGUIMessageBox::OnEvent(const SEvent& event)
256{
257 if (isEnabled())
258 {
259 SEvent outevent;
260 outevent.EventType = EET_GUI_EVENT;
261 outevent.GUIEvent.Caller = this;
262 outevent.GUIEvent.Element = 0;
263
264 switch(event.EventType)
265 {
266 case EET_KEY_INPUT_EVENT:
267
268 if (event.KeyInput.PressedDown)
269 {
270 switch (event.KeyInput.Key)
271 {
272 case KEY_RETURN:
273 if (OkButton)
274 {
275 OkButton->setPressed(true);
276 Pressed = true;
277 }
278 break;
279 case KEY_KEY_Y:
280 if (YesButton)
281 {
282 YesButton->setPressed(true);
283 Pressed = true;
284 }
285 break;
286 case KEY_KEY_N:
287 if (NoButton)
288 {
289 NoButton->setPressed(true);
290 Pressed = true;
291 }
292 break;
293 case KEY_ESCAPE:
294 if (Pressed)
295 {
296 // cancel press
297 if (OkButton) OkButton->setPressed(false);
298 if (YesButton) YesButton->setPressed(false);
299 if (NoButton) NoButton->setPressed(false);
300 Pressed = false;
301 }
302 else
303 if (CancelButton)
304 {
305 CancelButton->setPressed(true);
306 Pressed = true;
307 }
308 else
309 if (CloseButton && CloseButton->isVisible())
310 {
311 CloseButton->setPressed(true);
312 Pressed = true;
313 }
314 break;
315 default: // no other key is handled here
316 break;
317 }
318 }
319 else
320 if (Pressed)
321 {
322 if (OkButton && event.KeyInput.Key == KEY_RETURN)
323 {
324 setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
325 Environment->setFocus(0);
326 outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK;
327 Parent->OnEvent(outevent);
328 remove();
329 return true;
330 }
331 else
332 if ((CancelButton || CloseButton) && event.KeyInput.Key == KEY_ESCAPE)
333 {
334 setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
335 Environment->setFocus(0);
336 outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL;
337 Parent->OnEvent(outevent);
338 remove();
339 return true;
340 }
341 else
342 if (YesButton && event.KeyInput.Key == KEY_KEY_Y)
343 {
344 setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
345 Environment->setFocus(0);
346 outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES;
347 Parent->OnEvent(outevent);
348 remove();
349 return true;
350 }
351 else
352 if (NoButton && event.KeyInput.Key == KEY_KEY_N)
353 {
354 setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
355 Environment->setFocus(0);
356 outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO;
357 Parent->OnEvent(outevent);
358 remove();
359 return true;
360 }
361 }
362 break;
363 case EET_GUI_EVENT:
364 if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
365 {
366 if (event.GUIEvent.Caller == OkButton)
367 {
368 setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
369 Environment->setFocus(0);
370 outevent.GUIEvent.EventType = EGET_MESSAGEBOX_OK;
371 Parent->OnEvent(outevent);
372 remove();
373 return true;
374 }
375 else
376 if (event.GUIEvent.Caller == CancelButton ||
377 event.GUIEvent.Caller == CloseButton)
378 {
379 setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
380 Environment->setFocus(0);
381 outevent.GUIEvent.EventType = EGET_MESSAGEBOX_CANCEL;
382 Parent->OnEvent(outevent);
383 remove();
384 return true;
385 }
386 else
387 if (event.GUIEvent.Caller == YesButton)
388 {
389 setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
390 Environment->setFocus(0);
391 outevent.GUIEvent.EventType = EGET_MESSAGEBOX_YES;
392 Parent->OnEvent(outevent);
393 remove();
394 return true;
395 }
396 else
397 if (event.GUIEvent.Caller == NoButton)
398 {
399 setVisible(false); // this is a workaround to make sure it's no longer the hovered element, crashes on pressing 1-2 times ESC
400 Environment->setFocus(0);
401 outevent.GUIEvent.EventType = EGET_MESSAGEBOX_NO;
402 Parent->OnEvent(outevent);
403 remove();
404 return true;
405 }
406 }
407 break;
408 default:
409 break;
410 }
411 }
412
413 return CGUIWindow::OnEvent(event);
414}
415
416
417//! Writes attributes of the element.
418void CGUIMessageBox::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
419{
420 CGUIWindow::serializeAttributes(out,options);
421
422 out->addBool ("OkayButton", (Flags & EMBF_OK) != 0 );
423 out->addBool ("CancelButton", (Flags & EMBF_CANCEL) != 0 );
424 out->addBool ("YesButton", (Flags & EMBF_YES) != 0 );
425 out->addBool ("NoButton", (Flags & EMBF_NO) != 0 );
426 out->addTexture ("Texture", IconTexture);
427
428 out->addString ("MessageText", MessageText.c_str());
429}
430
431
432//! Reads attributes of the element
433void CGUIMessageBox::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
434{
435 Flags = 0;
436
437 Flags = in->getAttributeAsBool("OkayButton") ? EMBF_OK : 0;
438 Flags |= in->getAttributeAsBool("CancelButton")? EMBF_CANCEL : 0;
439 Flags |= in->getAttributeAsBool("YesButton") ? EMBF_YES : 0;
440 Flags |= in->getAttributeAsBool("NoButton") ? EMBF_NO : 0;
441
442 if ( IconTexture )
443 {
444 IconTexture->drop();
445 IconTexture = NULL;
446 }
447 IconTexture = in->getAttributeAsTexture("Texture");
448 if ( IconTexture )
449 IconTexture->grab();
450
451 MessageText = in->getAttributeAsStringW("MessageText").c_str();
452
453 CGUIWindow::deserializeAttributes(in,options);
454
455 refreshControls();
456}
457
458
459} // end namespace gui
460} // end namespace irr
461
462#endif // _IRR_COMPILE_WITH_GUI_
463