123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- // Copyright (C) 2002-2012 Nikolaus Gebhardt
- // This file is part of the "Irrlicht Engine".
- // For conditions of distribution and use, see copyright notice in irrlicht.h
- #include "CGUIWindow.h"
- #ifdef _IRR_COMPILE_WITH_GUI_
- #include "IGUISkin.h"
- #include "IGUIEnvironment.h"
- #include "IVideoDriver.h"
- #include "IGUIButton.h"
- #include "IGUIFont.h"
- #include "IGUIFontBitmap.h"
- namespace irr
- {
- namespace gui
- {
- //! constructor
- CGUIWindow::CGUIWindow(IGUIEnvironment* environment, IGUIElement* parent, s32 id, core::rect<s32> rectangle)
- : IGUIWindow(environment, parent, id, rectangle), Dragging(false), IsDraggable(true), DrawBackground(true), DrawTitlebar(true), IsActive(false)
- {
- #ifdef _DEBUG
- setDebugName("CGUIWindow");
- #endif
- IGUISkin* skin = 0;
- if (environment)
- skin = environment->getSkin();
- CurrentIconColor = video::SColor(255,255,255,255);
- s32 buttonw = 15;
- if (skin)
- {
- buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
- }
- s32 posx = RelativeRect.getWidth() - buttonw - 4;
- CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
- L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close" );
- CloseButton->setSubElement(true);
- CloseButton->setTabStop(false);
- CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
- posx -= buttonw + 2;
- RestoreButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
- L"", skin ? skin->getDefaultText(EGDT_WINDOW_RESTORE) : L"Restore" );
- RestoreButton->setVisible(false);
- RestoreButton->setSubElement(true);
- RestoreButton->setTabStop(false);
- RestoreButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
- posx -= buttonw + 2;
- MinButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
- L"", skin ? skin->getDefaultText(EGDT_WINDOW_MINIMIZE) : L"Minimize" );
- MinButton->setVisible(false);
- MinButton->setSubElement(true);
- MinButton->setTabStop(false);
- MinButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
- MinButton->grab();
- RestoreButton->grab();
- CloseButton->grab();
- // this element is a tab group
- setTabGroup(true);
- setTabStop(true);
- setTabOrder(-1);
- refreshSprites();
- updateClientRect();
- }
- //! destructor
- CGUIWindow::~CGUIWindow()
- {
- if (MinButton)
- MinButton->drop();
- if (RestoreButton)
- RestoreButton->drop();
- if (CloseButton)
- CloseButton->drop();
- }
- void CGUIWindow::refreshSprites()
- {
- if (!Environment)
- return;
- IGUISkin* skin = Environment->getSkin();
- if ( !skin )
- return;
- IGUISpriteBank* sprites = skin->getSpriteBank();
- if ( !sprites )
- return;
- CurrentIconColor = skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL);
- if (sprites)
- {
- CloseButton->setSpriteBank(sprites);
- CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), CurrentIconColor);
- CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), CurrentIconColor);
- RestoreButton->setSpriteBank(sprites);
- RestoreButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_RESTORE), CurrentIconColor);
- RestoreButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_RESTORE), CurrentIconColor);
- MinButton->setSpriteBank(sprites);
- MinButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_MINIMIZE), CurrentIconColor);
- MinButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_MINIMIZE), CurrentIconColor);
- }
- }
- //! called if an event happened.
- bool CGUIWindow::OnEvent(const SEvent& event)
- {
- if (isEnabled())
- {
- switch(event.EventType)
- {
- case EET_GUI_EVENT:
- if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
- {
- Dragging = false;
- IsActive = false;
- }
- else
- if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
- {
- if (Parent && ((event.GUIEvent.Caller == this) || isMyChild(event.GUIEvent.Caller)))
- {
- Parent->bringToFront(this);
- IsActive = true;
- }
- else
- {
- IsActive = false;
- }
- }
- else
- if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
- {
- if (event.GUIEvent.Caller == CloseButton)
- {
- if (Parent)
- {
- // send close event to parent
- SEvent e;
- e.EventType = EET_GUI_EVENT;
- e.GUIEvent.Caller = this;
- e.GUIEvent.Element = 0;
- e.GUIEvent.EventType = EGET_ELEMENT_CLOSED;
- // if the event was not absorbed
- if (!Parent->OnEvent(e))
- remove();
- return true;
- }
- else
- {
- remove();
- return true;
- }
- }
- }
- break;
- case EET_MOUSE_INPUT_EVENT:
- switch(event.MouseInput.Event)
- {
- case EMIE_LMOUSE_PRESSED_DOWN:
- DragStart.X = event.MouseInput.X;
- DragStart.Y = event.MouseInput.Y;
- Dragging = IsDraggable;
- if (Parent)
- Parent->bringToFront(this);
- return true;
- case EMIE_LMOUSE_LEFT_UP:
- Dragging = false;
- return true;
- case EMIE_MOUSE_MOVED:
- if (!event.MouseInput.isLeftPressed())
- Dragging = false;
- if (Dragging)
- {
- // gui window should not be dragged outside its parent
- if (Parent &&
- (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
- event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
- event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
- event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1))
- return true;
- move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
- DragStart.X = event.MouseInput.X;
- DragStart.Y = event.MouseInput.Y;
- return true;
- }
- break;
- default:
- break;
- }
- default:
- break;
- }
- }
- return IGUIElement::OnEvent(event);
- }
- //! Updates the absolute position.
- void CGUIWindow::updateAbsolutePosition()
- {
- IGUIElement::updateAbsolutePosition();
- }
- //! draws the element and its children
- void CGUIWindow::draw()
- {
- if (IsVisible)
- {
- IGUISkin* skin = Environment->getSkin();
- // update each time because the skin is allowed to change this always.
- updateClientRect();
- if ( CurrentIconColor != skin->getColor(isEnabled() ? EGDC_WINDOW_SYMBOL : EGDC_GRAY_WINDOW_SYMBOL) )
- refreshSprites();
- core::rect<s32> rect = AbsoluteRect;
- // draw body fast
- if (DrawBackground)
- {
- rect = skin->draw3DWindowBackground(this, DrawTitlebar,
- skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
- AbsoluteRect, &AbsoluteClippingRect);
- if (DrawTitlebar && Text.size())
- {
- rect.UpperLeftCorner.X += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_X);
- rect.UpperLeftCorner.Y += skin->getSize(EGDS_TITLEBARTEXT_DISTANCE_Y);
- rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
- IGUIFont* font = skin->getFont(EGDF_WINDOW);
- if (font)
- {
- font->draw(Text.c_str(), rect,
- skin->getColor(IsActive ? EGDC_ACTIVE_CAPTION:EGDC_INACTIVE_CAPTION),
- false, true, &AbsoluteClippingRect);
- }
- }
- }
- }
- IGUIElement::draw();
- }
- //! Returns pointer to the close button
- IGUIButton* CGUIWindow::getCloseButton() const
- {
- return CloseButton;
- }
- //! Returns pointer to the minimize button
- IGUIButton* CGUIWindow::getMinimizeButton() const
- {
- return MinButton;
- }
- //! Returns pointer to the maximize button
- IGUIButton* CGUIWindow::getMaximizeButton() const
- {
- return RestoreButton;
- }
- //! Returns true if the window is draggable, false if not
- bool CGUIWindow::isDraggable() const
- {
- return IsDraggable;
- }
- //! Sets whether the window is draggable
- void CGUIWindow::setDraggable(bool draggable)
- {
- IsDraggable = draggable;
- if (Dragging && !IsDraggable)
- Dragging = false;
- }
- //! Set if the window background will be drawn
- void CGUIWindow::setDrawBackground(bool draw)
- {
- DrawBackground = draw;
- }
- //! Get if the window background will be drawn
- bool CGUIWindow::getDrawBackground() const
- {
- return DrawBackground;
- }
- //! Set if the window titlebar will be drawn
- void CGUIWindow::setDrawTitlebar(bool draw)
- {
- DrawTitlebar = draw;
- }
- //! Get if the window titlebar will be drawn
- bool CGUIWindow::getDrawTitlebar() const
- {
- return DrawTitlebar;
- }
- void CGUIWindow::updateClientRect()
- {
- if (! DrawBackground )
- {
- ClientRect = core::rect<s32>(0,0, AbsoluteRect.getWidth(), AbsoluteRect.getHeight());
- return;
- }
- IGUISkin* skin = Environment->getSkin();
- skin->draw3DWindowBackground(this, DrawTitlebar,
- skin->getColor(IsActive ? EGDC_ACTIVE_BORDER : EGDC_INACTIVE_BORDER),
- AbsoluteRect, &AbsoluteClippingRect, &ClientRect);
- ClientRect -= AbsoluteRect.UpperLeftCorner;
- }
- //! Returns the rectangle of the drawable area (without border, without titlebar and without scrollbars)
- core::rect<s32> CGUIWindow::getClientRect() const
- {
- return ClientRect;
- }
- //! Writes attributes of the element.
- void CGUIWindow::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const
- {
- IGUIWindow::serializeAttributes(out,options);
- out->addBool("IsDraggable", IsDraggable);
- out->addBool("DrawBackground", DrawBackground);
- out->addBool("DrawTitlebar", DrawTitlebar);
- // Currently we can't just serialize attributes of sub-elements.
- // To do this we either
- // a) allow further serialization after attribute serialiation (second function, callback or event)
- // b) add an IGUIElement attribute
- // c) extend the attribute system to allow attributes to have sub-attributes
- // We just serialize the most important info for now until we can do one of the above solutions.
- out->addBool("IsCloseVisible", CloseButton->isVisible());
- out->addBool("IsMinVisible", MinButton->isVisible());
- out->addBool("IsRestoreVisible", RestoreButton->isVisible());
- }
- //! Reads attributes of the element
- void CGUIWindow::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0)
- {
- IGUIWindow::deserializeAttributes(in,options);
- Dragging = false;
- IsActive = false;
- IsDraggable = in->getAttributeAsBool("IsDraggable");
- DrawBackground = in->getAttributeAsBool("DrawBackground");
- DrawTitlebar = in->getAttributeAsBool("DrawTitlebar");
- CloseButton->setVisible(in->getAttributeAsBool("IsCloseVisible"));
- MinButton->setVisible(in->getAttributeAsBool("IsMinVisible"));
- RestoreButton->setVisible(in->getAttributeAsBool("IsRestoreVisible"));
- updateClientRect();
- }
- } // end namespace gui
- } // end namespace irr
- #endif // _IRR_COMPILE_WITH_GUI_
|