/* _______ __ __ __ ______ __ __ _______ __ __
* / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
* / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
* / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
* / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
* /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
* \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
*
* Copyright (c) 2004, 2005 darkbits Js_./
* Per Larsson a.k.a finalman _RqZ{a<^_aa
* Olof Naessén a.k.a jansem/yakslem _asww7!uY`> )\a//
* _Qhm`] _f "'c 1!5m
* Visit: http://guichan.darkbits.org )Qk
ws?a-?' ._/L #'
* binary forms, with or without )4d[#7r, . ' )d`)[
* modification, are permitted provided _Q-5'5W..j/?' -?!\)cam'
* that the following conditions are met: j<. a J@\
* this list of conditions and the j(]1u
#include "guichan/exception.h"
#include "guichan/focushandler.h"
#include "guichan/gui.h"
#include "guichan/key.h"
namespace gcn
{
Gui::Gui()
{
mTop = NULL;
mInput = NULL;
mGraphics = NULL;
mFocusHandler = new FocusHandler();
mTopHasMouse = false;
mTabbing = true;
mUseDirtyDrawing = true;
}
Gui::~Gui()
{
if (Widget::widgetExists(mTop))
{
setTop(NULL);
}
delete mFocusHandler;
}
void Gui::setTop(Widget* top)
{
if (mTop)
{
mTop->_setFocusHandler(NULL);
}
if (top)
{
top->_setFocusHandler(mFocusHandler);
top->setDirty(true);
}
mTop = top;
}
Widget* Gui::getTop() const
{
return mTop;
}
void Gui::setGraphics(Graphics* graphics)
{
mGraphics = graphics;
}
Graphics* Gui::getGraphics() const
{
return mGraphics;
}
void Gui::setInput(Input* input)
{
mInput = input;
}
Input* Gui::getInput() const
{
return mInput;
}
void Gui::logic()
{
if (!mTop)
{
assert(!"No top widget set");
//throw GCN_EXCEPTION("No top widget set");
}
if (mInput)
{
mInput->_pollInput();
while (!mInput->isMouseQueueEmpty())
{
MouseInput mi = mInput->dequeueMouseInput();
// Send mouse input to every widget that has the mouse.
if (mi.x > 0 && mi.y > 0
&& mTop->getDimension().isPointInRect(mi.x, mi.y))
{
if (!mTop->hasMouse())
{
mTop->_mouseInMessage();
}
MouseInput mio = mi;
mio.x -= mTop->getX();
mio.y -= mTop->getY();
mTop->_mouseInputMessage(mio);
}
else if (mTop->hasMouse())
{
mTop->_mouseOutMessage();
}
Widget* f = mFocusHandler->getFocused();
Widget* d = mFocusHandler->getDragged();
// If the focused widget doesn't have the mouse,
// send the mouse input to the focused widget.
if (f != NULL && !f->hasMouse())
{
int xOffset, yOffset;
f->getAbsolutePosition(xOffset, yOffset);
MouseInput mio = mi;
mio.x -= xOffset;
mio.y -= yOffset;
f->_mouseInputMessage(mio);
}
// If the dragged widget is different from the focused
// widget, send the mouse input to the dragged widget.
if (d != NULL && d != f && !d->hasMouse())
{
int xOffset, yOffset;
d->getAbsolutePosition(xOffset, yOffset);
MouseInput mio = mi;
mio.x -= xOffset;
mio.y -= yOffset;
d->_mouseInputMessage(mio);
}
mFocusHandler->applyChanges();
} // end while
while (!mInput->isKeyQueueEmpty())
{
KeyInput ki = mInput->dequeueKeyInput();
if (mTabbing
&& ki.getKey().getValue() == Key::K_TAB
&& ki.getType() == KeyInput::PRESS)
{
if (ki.getKey().isShiftPressed())
{
mFocusHandler->tabPrevious();
}
else
{
mFocusHandler->tabNext();
}
}
else
{
bool keyProcessed = false;
// Send key inputs to the focused widgets
if (mFocusHandler->getFocused())
{
if (mFocusHandler->getFocused()->isFocusable())
{
keyProcessed = mFocusHandler->getFocused()->_keyInputMessage(ki);
}
else
{
mFocusHandler->focusNone();
}
}
if (!keyProcessed)
{
mFocusHandler->checkHotKey(ki);
}
}
mFocusHandler->applyChanges();
} // end while
} // end if
mTop->logic();
}
void Gui::draw(Widget* top)
{
if (!top)
{
assert(!"No top widget set");
//throw GCN_EXCEPTION("No top widget set");
}
if (!mGraphics)
{
assert(!"No graphics set");
//throw GCN_EXCEPTION("No graphics set");
}
if (!mUseDirtyDrawing || top->getDirty())
{
mGraphics->_beginDraw();
// If top has a border,
// draw it before drawing top
if (top->getBorderSize() > 0)
{
Rectangle rec = top->getDimension();
rec.x -= top->getBorderSize();
rec.y -= top->getBorderSize();
rec.width += 2 * top->getBorderSize();
rec.height += 2 * top->getBorderSize();
mGraphics->pushClipArea(rec);
top->drawBorder(mGraphics);
mGraphics->popClipArea();
}
mGraphics->pushClipArea(top->getDimension());
top->draw(mGraphics);
top->setDirty(false);
mGraphics->popClipArea();
mGraphics->_endDraw();
}
}
void Gui::draw()
{
draw(mTop);
}
void Gui::focusNone()
{
mFocusHandler->focusNone();
}
void Gui::setTabbingEnabled(bool tabbing)
{
mTabbing = tabbing;
}
bool Gui::isTabbingEnabled()
{
return mTabbing;
}
void Gui::setUseDirtyDrawing(bool useDirtyDrawing)
{
mUseDirtyDrawing = useDirtyDrawing;
}
}