1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #include "CGUIWindow.h"
\r
6 #ifdef _IRR_COMPILE_WITH_GUI_
\r
8 #include "IGUISkin.h"
\r
9 #include "IGUIEnvironment.h"
\r
10 #include "IVideoDriver.h"
\r
11 #include "IGUIButton.h"
\r
12 #include "IGUIFont.h"
\r
13 #include "IGUIFontBitmap.h"
\r
21 CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
\r
22 : IGUIWindow(environment, parent, id, rectangle), Dragging(false), IsDraggable(true), DrawBackground(true), DrawTitlebar(true), IsActive(false)
\r
25 setDebugName("CGUIWindow");
\r
30 skin = environment->getSkin();
\r
32 CurrentIconColor = video::SColor(255,255,255,255);
\r
37 buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
\r
39 s32 posx = RelativeRect.getWidth() - buttonw - 4;
\r
41 CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
\r
42 L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close" );
\r
43 CloseButton->setSubElement(true);
\r
44 CloseButton->setTabStop(false);
\r
45 CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
\r
46 posx -= buttonw + 2;
\r
48 RestoreButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
\r
49 L"", skin ? skin->getDefaultText(EGDT_WINDOW_RESTORE) : L"Restore" );
\r
50 RestoreButton->setVisible(false);
\r
51 RestoreButton->setSubElement(true);
\r
52 RestoreButton->setTabStop(false);
\r
53 RestoreButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
\r
54 posx -= buttonw + 2;
\r
56 MinButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
\r
57 L"", skin ? skin->getDefaultText(EGDT_WINDOW_MINIMIZE) : L"Minimize" );
\r
58 MinButton->setVisible(false);
\r
59 MinButton->setSubElement(true);
\r
60 MinButton->setTabStop(false);
\r
61 MinButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
\r
64 RestoreButton->grab();
\r
65 CloseButton->grab();
\r
67 // this element is a tab group
\r
78 CGUIWindow::~CGUIWindow()
\r
84 RestoreButton->drop();
\r
87 CloseButton->drop();
\r
90 void CGUIWindow::refreshSprites()
\r
94 IGUISkin* skin = Environment->getSkin();
\r
98 IGUISpriteBank* sprites = skin->getSpriteBank();
\r
102 CurrentIconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL);
\r
106 CloseButton->setSpriteBank(sprites);
\r
107 CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), CurrentIconColor);
\r
108 CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), CurrentIconColor);
\r
110 RestoreButton->setSpriteBank(sprites);
\r
111 RestoreButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_RESTORE), CurrentIconColor);
\r
112 RestoreButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_RESTORE), CurrentIconColor);
\r
114 MinButton->setSpriteBank(sprites);
\r
115 MinButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_MINIMIZE), CurrentIconColor);
\r
116 MinButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_MINIMIZE), CurrentIconColor);
\r
120 //! called if an event happened.
\r
121 bool CGUIWindow::OnEvent(const SEvent& event)
\r
126 switch(event.EventType)
\r
128 case EET_GUI_EVENT:
\r
129 if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
\r
135 if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
\r
137 if (Parent && ((event.GUIEvent.Caller == this) || isMyChild(event.GUIEvent.Caller)))
\r
139 Parent->bringToFront(this);
\r
148 if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
\r
150 if (event.GUIEvent.Caller == CloseButton)
\r
154 // send close event to parent
\r
156 e.EventType = EET_GUI_EVENT;
\r
157 e.GUIEvent.Caller = this;
\r
158 e.GUIEvent.Element = 0;
\r
159 e.GUIEvent.EventType = EGET_ELEMENT_CLOSED;
\r
161 // if the event was not absorbed
\r
162 if (!Parent->OnEvent(e))
\r
176 case EET_MOUSE_INPUT_EVENT:
\r
177 switch(event.MouseInput.Event)
\r
179 case EMIE_LMOUSE_PRESSED_DOWN:
\r
180 DragStart.X = event.MouseInput.X;
\r
181 DragStart.Y = event.MouseInput.Y;
\r
182 Dragging = IsDraggable;
\r
184 Parent->bringToFront(this);
\r
186 case EMIE_LMOUSE_LEFT_UP:
\r
189 case EMIE_MOUSE_MOVED:
\r
190 if (!event.MouseInput.isLeftPressed())
\r
195 // gui window should not be dragged outside its parent
\r
197 (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
\r
198 event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
\r
199 event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
\r
200 event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1))
\r
203 move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
\r
204 DragStart.X = event.MouseInput.X;
\r
205 DragStart.Y = event.MouseInput.Y;
\r
217 return IGUIElement::OnEvent(event);
\r
221 //! Updates the absolute position.
\r
222 void CGUIWindow::updateAbsolutePosition()
\r
224 IGUIElement::updateAbsolutePosition();
\r
228 //! draws the element and its children
\r
229 void CGUIWindow::draw()
\r
233 IGUISkin* skin = Environment->getSkin();
\r
236 // update each time because the skin is allowed to change this always.
\r
237 updateClientRect();
\r
239 if ( CurrentIconColor != skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL) )
\r
242 core::rect<s32> rect = AbsoluteRect;
\r
245 if (DrawBackground)
\r
247 rect = skin->draw3DWindowBackground(this, DrawTitlebar,
\r
248 skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
\r
249 AbsoluteRect, &AbsoluteClippingRect);
\r
251 if (DrawTitlebar && Text.size())
\r
253 rect.UpperLeftCorner.X += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_X);
\r
254 rect.UpperLeftCorner.Y += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_Y);
\r
255 rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
\r
257 IGUIFont* font = skin->getFont(EGDF_WINDOW);
\r
260 font->draw(Text.c_str(), rect,
\r
261 skin->getColor(IsActive ? EGDC_ACTIVE_CAPTION:EGDC_INACTIVE_CAPTION),
\r
262 false, true, &AbsoluteClippingRect);
\r
268 IGUIElement::draw();
\r
272 //! Returns pointer to the close button
\r
273 IGUIButton* CGUIWindow::getCloseButton() const
\r
275 return CloseButton;
\r
279 //! Returns pointer to the minimize button
\r
280 IGUIButton* CGUIWindow::getMinimizeButton() const
\r
286 //! Returns pointer to the maximize button
\r
287 IGUIButton* CGUIWindow::getMaximizeButton() const
\r
289 return RestoreButton;
\r
293 //! Returns true if the window is draggable, false if not
\r
294 bool CGUIWindow::isDraggable() const
\r
296 return IsDraggable;
\r
300 //! Sets whether the window is draggable
\r
301 void CGUIWindow::setDraggable(bool draggable)
\r
303 IsDraggable = draggable;
\r
305 if (Dragging && !IsDraggable)
\r
310 //! Set if the window background will be drawn
\r
311 void CGUIWindow::setDrawBackground(bool draw)
\r
313 DrawBackground = draw;
\r
317 //! Get if the window background will be drawn
\r
318 bool CGUIWindow::getDrawBackground() const
\r
320 return DrawBackground;
\r
324 //! Set if the window titlebar will be drawn
\r
325 void CGUIWindow::setDrawTitlebar(bool draw)
\r
327 DrawTitlebar = draw;
\r
331 //! Get if the window titlebar will be drawn
\r
332 bool CGUIWindow::getDrawTitlebar() const
\r
334 return DrawTitlebar;
\r
338 void CGUIWindow::updateClientRect()
\r
340 if (! DrawBackground )
\r
342 ClientRect = core::rect<s32>(0,0, AbsoluteRect.getWidth(), AbsoluteRect.getHeight());
\r
345 IGUISkin* skin = Environment->getSkin();
\r
346 skin->draw3DWindowBackground(this, DrawTitlebar,
\r
347 skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
\r
348 AbsoluteRect, &AbsoluteClippingRect, &ClientRect);
\r
349 ClientRect -= AbsoluteRect.UpperLeftCorner;
\r
353 //! Returns the rectangle of the drawable area (without border, without titlebar and without scrollbars)
\r
354 core::rect<s32> CGUIWindow::getClientRect() const
\r
360 //! Writes attributes of the element.
\r
361 void CGUIWindow::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
\r
363 IGUIWindow::serializeAttributes(out,options);
\r
365 out->addBool("IsDraggable", IsDraggable);
\r
366 out->addBool("DrawBackground", DrawBackground);
\r
367 out->addBool("DrawTitlebar", DrawTitlebar);
\r
369 // Currently we can't just serialize attributes of sub-elements.
\r
370 // To do this we either
\r
371 // a) allow further serialization after attribute serialiation (second function, callback or event)
\r
372 // b) add an IGUIElement attribute
\r
373 // c) extend the attribute system to allow attributes to have sub-attributes
\r
374 // We just serialize the most important info for now until we can do one of the above solutions.
\r
375 out->addBool("IsCloseVisible", CloseButton->isVisible());
\r
376 out->addBool("IsMinVisible", MinButton->isVisible());
\r
377 out->addBool("IsRestoreVisible", RestoreButton->isVisible());
\r
381 //! Reads attributes of the element
\r
382 void CGUIWindow::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
\r
384 IGUIWindow::deserializeAttributes(in,options);
\r
388 IsDraggable = in->getAttributeAsBool("IsDraggable");
\r
389 DrawBackground = in->getAttributeAsBool("DrawBackground");
\r
390 DrawTitlebar = in->getAttributeAsBool("DrawTitlebar");
\r
392 CloseButton->setVisible(in->getAttributeAsBool("IsCloseVisible"));
\r
393 MinButton->setVisible(in->getAttributeAsBool("IsMinVisible"));
\r
394 RestoreButton->setVisible(in->getAttributeAsBool("IsRestoreVisible"));
\r
396 updateClientRect();
\r
400 } // end namespace gui
\r
401 } // end namespace irr
\r
403 #endif // _IRR_COMPILE_WITH_GUI_
\r