summaryrefslogtreecommitdiff
path: root/src/gui/base
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-02-15 18:07:17 +0300
committerAndrei Karas <akaras@inbox.ru>2014-02-15 18:38:03 +0300
commitcde42202d69e178da73c698065deca54b24054fd (patch)
treed636965ecde85db8de36fa65735920826e8e191b /src/gui/base
parent21e63bbf54679ec236d1f09ed435959ff6a04db2 (diff)
downloadmanaplus-cde42202d69e178da73c698065deca54b24054fd.tar.gz
manaplus-cde42202d69e178da73c698065deca54b24054fd.tar.bz2
manaplus-cde42202d69e178da73c698065deca54b24054fd.tar.xz
manaplus-cde42202d69e178da73c698065deca54b24054fd.zip
move exguichan files into gui/base/
Diffstat (limited to 'src/gui/base')
-rw-r--r--src/gui/base/actionevent.cpp88
-rw-r--r--src/gui/base/actionevent.hpp133
-rw-r--r--src/gui/base/actionlistener.hpp112
-rw-r--r--src/gui/base/basiccontainer.cpp394
-rw-r--r--src/gui/base/basiccontainer.hpp216
-rw-r--r--src/gui/base/cliprectangle.cpp107
-rw-r--r--src/gui/base/cliprectangle.hpp129
-rw-r--r--src/gui/base/color.cpp165
-rw-r--r--src/gui/base/color.hpp192
-rw-r--r--src/gui/base/deathlistener.hpp109
-rw-r--r--src/gui/base/event.cpp87
-rw-r--r--src/gui/base/event.hpp113
-rw-r--r--src/gui/base/exception.cpp120
-rw-r--r--src/gui/base/exception.hpp196
-rw-r--r--src/gui/base/focushandler.cpp571
-rw-r--r--src/gui/base/focushandler.hpp417
-rw-r--r--src/gui/base/focuslistener.hpp119
-rw-r--r--src/gui/base/font.cpp87
-rw-r--r--src/gui/base/font.hpp133
-rw-r--r--src/gui/base/graphics.cpp179
-rw-r--r--src/gui/base/graphics.hpp294
-rw-r--r--src/gui/base/gui.cpp765
-rw-r--r--src/gui/base/gui.hpp514
-rw-r--r--src/gui/base/image.cpp83
-rw-r--r--src/gui/base/image.hpp162
-rw-r--r--src/gui/base/input.hpp134
-rw-r--r--src/gui/base/inputevent.cpp117
-rw-r--r--src/gui/base/inputevent.hpp177
-rw-r--r--src/gui/base/key.cpp113
-rw-r--r--src/gui/base/key.hpp201
-rw-r--r--src/gui/base/keyevent.cpp111
-rw-r--r--src/gui/base/keyevent.hpp157
-rw-r--r--src/gui/base/keyinput.cpp154
-rw-r--r--src/gui/base/keyinput.hpp289
-rw-r--r--src/gui/base/keylistener.hpp119
-rw-r--r--src/gui/base/listmodel.hpp106
-rw-r--r--src/gui/base/mouseevent.cpp121
-rw-r--r--src/gui/base/mouseevent.hpp217
-rw-r--r--src/gui/base/mouseinput.cpp136
-rw-r--r--src/gui/base/mouseinput.hpp260
-rw-r--r--src/gui/base/mouselistener.hpp196
-rw-r--r--src/gui/base/rectangle.cpp156
-rw-r--r--src/gui/base/rectangle.hpp159
-rw-r--r--src/gui/base/sdl/sdlpixel.hpp306
-rw-r--r--src/gui/base/selectionevent.cpp82
-rw-r--r--src/gui/base/selectionevent.hpp98
-rw-r--r--src/gui/base/selectionlistener.hpp117
-rw-r--r--src/gui/base/widget.cpp695
-rw-r--r--src/gui/base/widget.hpp1232
-rw-r--r--src/gui/base/widgetlistener.hpp143
-rw-r--r--src/gui/base/widgets/button.cpp194
-rw-r--r--src/gui/base/widgets/button.hpp220
-rw-r--r--src/gui/base/widgets/checkbox.cpp154
-rw-r--r--src/gui/base/widgets/checkbox.hpp180
-rw-r--r--src/gui/base/widgets/container.cpp136
-rw-r--r--src/gui/base/widgets/container.hpp180
-rw-r--r--src/gui/base/widgets/label.cpp121
-rw-r--r--src/gui/base/widgets/label.hpp154
-rw-r--r--src/gui/base/widgets/listbox.cpp241
-rw-r--r--src/gui/base/widgets/listbox.hpp275
-rw-r--r--src/gui/base/widgets/radiobutton.cpp207
-rw-r--r--src/gui/base/widgets/radiobutton.hpp226
-rw-r--r--src/gui/base/widgets/scrollarea.cpp600
-rw-r--r--src/gui/base/widgets/scrollarea.hpp549
-rw-r--r--src/gui/base/widgets/slider.cpp231
-rw-r--r--src/gui/base/widgets/slider.hpp293
-rw-r--r--src/gui/base/widgets/textbox.cpp345
-rw-r--r--src/gui/base/widgets/textbox.hpp310
-rw-r--r--src/gui/base/widgets/textfield.cpp165
-rw-r--r--src/gui/base/widgets/textfield.hpp190
-rw-r--r--src/gui/base/widgets/window.cpp233
-rw-r--r--src/gui/base/widgets/window.hpp269
72 files changed, 16554 insertions, 0 deletions
diff --git a/src/gui/base/actionevent.cpp b/src/gui/base/actionevent.cpp
new file mode 100644
index 000000000..7fcc1ee84
--- /dev/null
+++ b/src/gui/base/actionevent.cpp
@@ -0,0 +1,88 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/actionevent.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ ActionEvent::ActionEvent(Widget *const source, const std::string &id)
+ :Event(source),
+ mId(id)
+ {
+ }
+
+ ActionEvent::~ActionEvent()
+ {
+ }
+
+ const std::string& ActionEvent::getId() const
+ {
+ return mId;
+ }
+} // namespace gcn
diff --git a/src/gui/base/actionevent.hpp b/src/gui/base/actionevent.hpp
new file mode 100644
index 000000000..621499864
--- /dev/null
+++ b/src/gui/base/actionevent.hpp
@@ -0,0 +1,133 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_ACTIONEVENT_HPP
+#define GCN_ACTIONEVENT_HPP
+
+#include "gui/base/event.hpp"
+
+#include <string>
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ class Widget;
+
+ /**
+ * Represents an action event. An action event is an event
+ * that can be fired by a widget whenever an action has occured.
+ * What exactly an action is is up to the widget that fires
+ * the action event. An example is a Button which fires an action
+ * event as soon as the Button is clicked, another example is
+ * TextField which fires an action event as soon as the enter
+ * key is pressed.
+ *
+ * Any object can listen for actions from widgets by implementing
+ * the ActionListener interface.
+ *
+ * If you have implement a widget of your own it's a good idea to
+ * let the widget fire action events whenever you feel an action
+ * has occured so action listeners of the widget can be informed
+ * of the state of the widget.
+ *
+ * @see Widget::addActionListener, Widget::removeActionListener,
+ * Widget::distributeActionEvent
+ * @author Olof Naessén
+ * @since 0.6.0
+ */
+ class ActionEvent final : public Event
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param source The source widget of the event.
+ * @param id An identifier of the event.
+ */
+ ActionEvent(Widget *const source, const std::string &id);
+
+ /**
+ * Destructor.
+ */
+ virtual ~ActionEvent();
+
+ /**
+ * Gets the identifier of the event. An identifier can
+ * be used to distinguish from two actions from the same
+ * widget or to let many widgets fire the same widgets
+ * that should be treated equally.
+ *
+ * @return The identifier of the event.
+ */
+ const std::string& getId() const A_WARN_UNUSED;
+
+ protected:
+ /**
+ * Holds the identifier of the event.
+ */
+ std::string mId;
+ };
+} // namespace gcn
+
+#endif // GCN_ACTIONEVENT_HPP
diff --git a/src/gui/base/actionlistener.hpp b/src/gui/base/actionlistener.hpp
new file mode 100644
index 000000000..8a40fbb8c
--- /dev/null
+++ b/src/gui/base/actionlistener.hpp
@@ -0,0 +1,112 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_ACTIONLISTENER_HPP
+#define GCN_ACTIONLISTENER_HPP
+
+#include <string>
+
+#include "gui/base/actionevent.hpp"
+
+namespace gcn
+{
+ /**
+ * Interface for listening for action events from widgets.
+ *
+ * @see Widget::addActionListener, Widget::removeActionListener,
+ * ActionEvent
+ * @author Olof Naessén
+ * @author Per Larsson
+ */
+ class ActionListener
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~ActionListener()
+ { }
+
+ /**
+ * Called when an action is recieved from a widget. It is used
+ * to be able to recieve a notification that an action has
+ * occured.
+ *
+ * @param actionEvent The event of the action.
+ * @since 0.6.0
+ */
+ virtual void action(const ActionEvent& actionEvent) = 0;
+
+ protected:
+ /**
+ * Constructor.
+ *
+ * You should not be able to make an instance of ActionListener,
+ * therefore its constructor is protected.
+ */
+ ActionListener()
+ { }
+ };
+} // namespace gcn
+
+#endif // end GCN_ACTIONLISTENER_HPP
diff --git a/src/gui/base/basiccontainer.cpp b/src/gui/base/basiccontainer.cpp
new file mode 100644
index 000000000..45bb1e231
--- /dev/null
+++ b/src/gui/base/basiccontainer.cpp
@@ -0,0 +1,394 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/basiccontainer.hpp"
+
+#include <algorithm>
+
+#include "gui/base/exception.hpp"
+#include "gui/base/focushandler.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ BasicContainer::~BasicContainer()
+ {
+ clear();
+ }
+
+ void BasicContainer::moveToTop(Widget* widget)
+ {
+ for (WidgetListIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++ iter)
+ {
+ if (*iter == widget)
+ {
+ mWidgets.erase(iter);
+ mWidgets.push_back(widget);
+ return;
+ }
+ }
+
+ throw GCN_EXCEPTION("There is no such widget in this container.");
+ }
+
+ void BasicContainer::moveToBottom(Widget* widget)
+ {
+ WidgetListIterator iter;
+ iter = std::find(mWidgets.begin(), mWidgets.end(), widget);
+
+ if (iter == mWidgets.end())
+ throw GCN_EXCEPTION("There is no such widget in this container.");
+
+ mWidgets.erase(iter);
+ mWidgets.insert(mWidgets.begin(), widget);
+// mWidgets.push_front(widget);
+ }
+
+ void BasicContainer::death(const Event& event)
+ {
+ WidgetListIterator iter;
+ iter = std::find(mWidgets.begin(), mWidgets.end(), event.getSource());
+
+ if (iter == mWidgets.end())
+ throw GCN_EXCEPTION("There is no such widget in this container.");
+
+ mWidgets.erase(iter);
+ }
+
+ Rectangle BasicContainer::getChildrenArea()
+ {
+ return Rectangle(0, 0, getWidth(), getHeight());
+ }
+
+ void BasicContainer::focusNext()
+ {
+ WidgetListConstIterator it;
+
+ for (it = mWidgets.begin(); it != mWidgets.end(); ++ it)
+ {
+ if ((*it)->isFocused())
+ break;
+ }
+
+ WidgetListConstIterator end = it;
+
+ if (it == mWidgets.end())
+ it = mWidgets.begin();
+
+ ++ it;
+
+ for ( ; it != end; ++ it)
+ {
+ if (it == mWidgets.end())
+ it = mWidgets.begin();
+
+ if ((*it)->isFocusable())
+ {
+ (*it)->requestFocus();
+ return;
+ }
+ }
+ }
+
+ void BasicContainer::focusPrevious()
+ {
+ WidgetListReverseIterator it;
+
+ for (it = mWidgets.rbegin(); it != mWidgets.rend(); ++ it)
+ {
+ if ((*it)->isFocused())
+ break;
+ }
+
+ const WidgetListReverseIterator end = it;
+
+ ++ it;
+
+ if (it == mWidgets.rend())
+ it = mWidgets.rbegin();
+
+ for ( ; it != end; ++ it)
+ {
+ if (it == mWidgets.rend())
+ it = mWidgets.rbegin();
+
+ if ((*it)->isFocusable())
+ {
+ (*it)->requestFocus();
+ return;
+ }
+ }
+ }
+
+ Widget *BasicContainer::getWidgetAt(int x, int y)
+ {
+ const Rectangle r = getChildrenArea();
+
+ if (!r.isPointInRect(x, y))
+ return nullptr;
+
+ x -= r.x;
+ y -= r.y;
+
+ for (WidgetListReverseIterator it = mWidgets.rbegin();
+ it != mWidgets.rend(); ++ it)
+ {
+ if ((*it)->isVisible() && (*it)->getDimension()
+ .isPointInRect(x, y))
+ {
+ return (*it);
+ }
+ }
+
+ return nullptr;
+ }
+
+ void BasicContainer::logic()
+ {
+ BLOCK_START("BasicContainer::logic")
+ logicChildren();
+ BLOCK_END("BasicContainer::logic")
+ }
+
+ void BasicContainer::_setFocusHandler(FocusHandler* focusHandler)
+ {
+ Widget::_setFocusHandler(focusHandler);
+
+ if (mInternalFocusHandler)
+ return;
+
+ for (WidgetListConstIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++ iter)
+ {
+ (*iter)->_setFocusHandler(focusHandler);
+ }
+ }
+
+ void BasicContainer::add(Widget* widget)
+ {
+ mWidgets.push_back(widget);
+
+ if (!mInternalFocusHandler)
+ widget->_setFocusHandler(_getFocusHandler());
+ else
+ widget->_setFocusHandler(mInternalFocusHandler);
+
+ widget->_setParent(this);
+ widget->addDeathListener(this);
+ }
+
+ void BasicContainer::remove(Widget* widget)
+ {
+ for (WidgetListIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++ iter)
+ {
+ if (*iter == widget)
+ {
+ mWidgets.erase(iter);
+ widget->_setFocusHandler(nullptr);
+ widget->_setParent(nullptr);
+ widget->removeDeathListener(this);
+ return;
+ }
+ }
+
+ throw GCN_EXCEPTION("There is no such widget in this container.");
+ }
+
+ void BasicContainer::clear()
+ {
+ for (WidgetListConstIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++ iter)
+ {
+ (*iter)->_setFocusHandler(nullptr);
+ (*iter)->_setParent(nullptr);
+ (*iter)->removeDeathListener(this);
+ }
+
+ mWidgets.clear();
+ }
+
+ void BasicContainer::drawChildren(Graphics* graphics)
+ {
+ BLOCK_START("BasicContainer::drawChildren")
+
+ graphics->pushClipArea(getChildrenArea());
+
+ for (WidgetListConstIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++ iter)
+ {
+ Widget *const widget = *iter;
+ if (widget->isVisible())
+ {
+ // If the widget has a frame,
+ // draw it before drawing the widget
+ if (widget->getFrameSize() > 0)
+ {
+ Rectangle rec = widget->getDimension();
+ const int frame = widget->getFrameSize();
+ const int frame2 = frame * 2;
+ rec.x -= frame;
+ rec.y -= frame;
+ rec.width += frame2;
+ rec.height += frame2;
+ graphics->pushClipArea(rec);
+ BLOCK_START("BasicContainer::drawChildren 1")
+ widget->drawFrame(graphics);
+ BLOCK_END("BasicContainer::drawChildren 1")
+ graphics->popClipArea();
+ }
+
+ graphics->pushClipArea(widget->getDimension());
+ BLOCK_START("BasicContainer::drawChildren 2")
+ widget->draw(graphics);
+ BLOCK_END("BasicContainer::drawChildren 2")
+ graphics->popClipArea();
+ }
+ }
+
+ graphics->popClipArea();
+ BLOCK_END("BasicContainer::drawChildren")
+ }
+
+ void BasicContainer::logicChildren()
+ {
+ BLOCK_START("BasicContainer::logicChildren")
+ for (WidgetListConstIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++ iter)
+ {
+ (*iter)->logic();
+ }
+ BLOCK_END("BasicContainer::logicChildren")
+ }
+
+ void BasicContainer::showWidgetPart(Widget* widget, Rectangle area)
+ {
+ const Rectangle widgetArea = getChildrenArea();
+
+ area.x += widget->getX();
+ area.y += widget->getY();
+
+ if (area.x + area.width > widgetArea.width)
+ {
+ widget->setX(widget->getX() - area.x
+ - area.width + widgetArea.width);
+ }
+
+ if (area.y + area.height > widgetArea.height)
+ {
+ widget->setY(widget->getY() - area.y
+ - area.height + widgetArea.height);
+ }
+
+ if (area.x < 0)
+ widget->setX(widget->getX() - area.x);
+
+ if (area.y < 0)
+ widget->setY(widget->getY() - area.y);
+ }
+
+ void BasicContainer::setInternalFocusHandler(FocusHandler* focusHandler)
+ {
+ Widget::setInternalFocusHandler(focusHandler);
+
+ for (WidgetListConstIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++ iter)
+ {
+ if (!mInternalFocusHandler)
+ (*iter)->_setFocusHandler(_getFocusHandler());
+ else
+ (*iter)->_setFocusHandler(mInternalFocusHandler);
+ }
+ }
+
+ Widget* BasicContainer::findWidgetById(const std::string& id)
+ {
+ for (WidgetListConstIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++ iter)
+ {
+ if ((*iter)->getId() == id)
+ return (*iter);
+
+ BasicContainer *const basicContainer
+ = dynamic_cast<BasicContainer *const>(*iter);
+
+ if (basicContainer)
+ {
+ Widget *const widget = basicContainer->findWidgetById(id);
+
+ if (widget)
+ return widget;
+ }
+ }
+
+ return nullptr;
+ }
+} // namespace gcn
diff --git a/src/gui/base/basiccontainer.hpp b/src/gui/base/basiccontainer.hpp
new file mode 100644
index 000000000..d6dd38b63
--- /dev/null
+++ b/src/gui/base/basiccontainer.hpp
@@ -0,0 +1,216 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_BASICCONTAINER_HPP
+#define GCN_BASICCONTAINER_HPP
+
+#include <list>
+#include <vector>
+
+#include "gui/base/deathlistener.hpp"
+#include "gui/base/widget.hpp"
+
+namespace gcn
+{
+ /**
+ * A base class for containers. The class implements the most
+ * common things for a container. If you are implementing a
+ * container, consider inheriting from this class.
+ *
+ * @see Container
+ * @since 0.6.0
+ */
+ class BasicContainer : public Widget,
+ public DeathListener
+ {
+ public:
+ BasicContainer() :
+ mWidgets()
+ { }
+
+ A_DELETE_COPY(BasicContainer)
+
+ /**
+ * Destructor
+ */
+ virtual ~BasicContainer();
+
+ /**
+ * Shows a certain part of a widget in the basic container.
+ * Used when widgets want a specific part to be visible in
+ * its parent. An example is a TextArea that wants a specific
+ * part of its text to be visible when a TextArea is a child
+ * of a ScrollArea.
+ *
+ * @param widget The widget whom wants a specific part of
+ * itself to be visible.
+ * @param rectangle The rectangle to be visible.
+ */
+ virtual void showWidgetPart(Widget* widget, Rectangle area);
+
+ // Inherited from Widget
+
+ virtual void moveToTop(Widget* widget);
+
+ virtual void moveToBottom(Widget* widget);
+
+ virtual Rectangle getChildrenArea() A_WARN_UNUSED;
+
+ virtual void focusNext();
+
+ virtual void focusPrevious();
+
+ virtual void logic();
+
+ virtual void _setFocusHandler(FocusHandler* focusHandler);
+
+ void setInternalFocusHandler(FocusHandler* focusHandler);
+
+ virtual Widget *getWidgetAt(int x, int y) A_WARN_UNUSED;
+
+
+ // Inherited from DeathListener
+
+ virtual void death(const Event& event);
+
+ protected:
+ /**
+ * Adds a widget to the basic container.
+ *
+ * @param widget The widget to add.
+ * @see remove, clear
+ */
+ void add(Widget* widget);
+
+ /**
+ * Removes a widget from the basic container.
+ *
+ * @param widget The widget to remove.
+ * @see add, clear
+ */
+ virtual void remove(Widget* widget);
+
+ /**
+ * Clears the basic container from all widgets.
+ *
+ * @see remove, clear
+ */
+ virtual void clear();
+
+ /**
+ * Draws the children widgets of the basic container.
+ *
+ * @param graphics A graphics object to draw with.
+ */
+ virtual void drawChildren(Graphics* graphics);
+
+ /**
+ * Calls logic for the children widgets of the basic
+ * container.
+ */
+ virtual void logicChildren();
+
+ /**
+ * Finds a widget given an id. This function can be useful
+ * when implementing a GUI generator for Guichan, such as
+ * the ability to create a Guichan GUI from an XML file.
+ *
+ * @param id The id to find a widget by.
+ * @return The widget with the corrosponding id,
+ NULL of no widget is found.
+ */
+ virtual Widget* findWidgetById(const std::string& id) A_WARN_UNUSED;
+
+ /**
+ * Typedef.
+ */
+ typedef std::vector<Widget *> WidgetList;
+
+ /**
+ * Typedef.
+ */
+ typedef WidgetList::iterator WidgetListIterator;
+
+ /**
+ * Typedef.
+ */
+ typedef WidgetList::const_iterator WidgetListConstIterator;
+
+ /**
+ * Typedef.
+ */
+ typedef WidgetList::reverse_iterator WidgetListReverseIterator;
+
+ /**
+ * Typedef.
+ */
+ typedef WidgetList::const_reverse_iterator WidgetListCReverseIterator;
+
+ /**
+ * Holds all widgets of the basic container.
+ */
+ WidgetList mWidgets;
+ };
+} // namespace gcn
+
+#endif // end GCN_BASICCONTAINER_HPP
diff --git a/src/gui/base/cliprectangle.cpp b/src/gui/base/cliprectangle.cpp
new file mode 100644
index 000000000..f52bc384a
--- /dev/null
+++ b/src/gui/base/cliprectangle.cpp
@@ -0,0 +1,107 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/cliprectangle.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ ClipRectangle::ClipRectangle() :
+ Rectangle(),
+ xOffset(0),
+ yOffset(0)
+ {
+ x = 0;
+ y = 0;
+ width = 0;
+ height = 0;
+ }
+
+ ClipRectangle::ClipRectangle(const int x0, const int y0,
+ const int width0, const int height0,
+ const int xOffset0, const int yOffset0) :
+ Rectangle(),
+ xOffset(xOffset0),
+ yOffset(yOffset0)
+ {
+ x = x0;
+ y = y0;
+ width = width0;
+ height = height0;
+ }
+
+ const ClipRectangle& ClipRectangle::operator=(const Rectangle& other)
+ {
+ x = other.x;
+ y = other.y;
+ width = other.width;
+ height = other.height;
+
+ return *this;
+ }
+} // namespace gcn
diff --git a/src/gui/base/cliprectangle.hpp b/src/gui/base/cliprectangle.hpp
new file mode 100644
index 000000000..1fdbfbe8d
--- /dev/null
+++ b/src/gui/base/cliprectangle.hpp
@@ -0,0 +1,129 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_CLIPRECTANGLE_HPP
+#define GCN_CLIPRECTANGLE_HPP
+
+#include "gui/base/rectangle.hpp"
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ /**
+ * A rectangle used when dealing with clipping. A clip rectangle is
+ * a regular rectangle extended with variables for x offsets and y
+ * offsets. The offsets are used for calculations from relative
+ * screen coordinates to actual screen coordinates.
+ */
+ class ClipRectangle final : public Rectangle
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ ClipRectangle();
+
+ /**
+ * Constructor.
+ *
+ * @param x0 The rectangle x coordinate.
+ * @param y0 The rectangle y coordinate.
+ * @param width0 The rectangle width.
+ * @param height0 The rectangle height.
+ * @param xOffset0 The offset of the x coordinate. Used to for
+ * calculating the actual screen coordinate from
+ * the relative screen coordinate.
+ * @param yOffset0 The offset of the y coordinate. Used to for
+ * calculating the actual screen coordinate from
+ * the relative screen coordinate.
+ */
+ ClipRectangle(const int x0,
+ const int y0,
+ const int width0,
+ const int height0,
+ const int xOffset0,
+ const int yOffset0);
+
+ /**
+ * Copy constructor. Copies x, y, width and height
+ * field from a rectangle to a clip rectangle.
+ *
+ * @param other The rectangle to copy data from.
+ * @returns A clip rectangle with data copyied from a rectangle.
+ */
+ const ClipRectangle& operator=(const Rectangle& other);
+
+ /**
+ * Holds the x offset of the x coordinate.
+ */
+ int xOffset;
+
+ /**
+ * Holds the y offset of the y coordinate.
+ */
+ int yOffset;
+ };
+} // namespace gcn
+
+#endif // end GCN_CLIPRECTANGLE_HPP
diff --git a/src/gui/base/color.cpp b/src/gui/base/color.cpp
new file mode 100644
index 000000000..764259efc
--- /dev/null
+++ b/src/gui/base/color.cpp
@@ -0,0 +1,165 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/color.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Color::Color() :
+ r(0),
+ g(0),
+ b(0),
+ a(255)
+ {
+ }
+
+ Color::Color(const int color) :
+ r((color >> 16) & 0xFF),
+ g((color >> 8) & 0xFF),
+ b(color & 0xFF),
+ a(255)
+ {
+ }
+
+ Color::Color(const int ar, const int ag, const int ab, const int aa) :
+ r(ar),
+ g(ag),
+ b(ab),
+ a(aa)
+ {
+ }
+
+ Color Color::operator+(const Color& color) const
+ {
+ Color result(r + color.r,
+ g + color.g,
+ b + color.b,
+ 255);
+
+ result.r = (result.r>255?255:(result.r<0?0:result.r));
+ result.g = (result.g>255?255:(result.g<0?0:result.g));
+ result.b = (result.b>255?255:(result.b<0?0:result.b));
+
+ return result;
+ }
+
+ Color Color::operator-(const Color& color) const
+ {
+ Color result(r - color.r,
+ g - color.g,
+ b - color.b,
+ 255);
+
+ result.r = (result.r > 255 ? 255 : (result.r < 0 ? 0 : result.r));
+ result.g = (result.g > 255 ? 255 : (result.g < 0 ? 0 : result.g));
+ result.b = (result.b > 255 ? 255 : (result.b < 0 ? 0 : result.b));
+
+ return result;
+ }
+
+ Color Color::operator*(const float value) const
+ {
+ Color result(static_cast<int>(static_cast<float>(r) * value),
+ static_cast<int>(static_cast<float>(g) * value),
+ static_cast<int>(static_cast<float>(b) * value),
+ a);
+
+ result.r = (result.r > 255 ? 255 : (result.r < 0 ? 0 : result.r));
+ result.g = (result.g > 255 ? 255 : (result.g < 0 ? 0 : result.g));
+ result.b = (result.b > 255 ? 255 : (result.b < 0 ? 0 : result.b));
+
+ return result;
+ }
+
+ bool Color::operator==(const Color& color) const
+ {
+ return r == color.r && g == color.g && b == color.b && a == color.a;
+ }
+
+ bool Color::operator!=(const Color& color) const
+ {
+ return !(r == color.r && g == color.g && b == color.b && a == color.a);
+ }
+
+ std::ostream& operator<<(std::ostream& out,
+ const Color& color)
+ {
+ out << "Color [r = "
+ << color.r
+ << ", g = "
+ << color.g
+ << ", b = "
+ << color.b
+ << ", a = "
+ << color.a
+ << "]";
+
+ return out;
+ }
+} // namespace gcn
diff --git a/src/gui/base/color.hpp b/src/gui/base/color.hpp
new file mode 100644
index 000000000..c32adb2e9
--- /dev/null
+++ b/src/gui/base/color.hpp
@@ -0,0 +1,192 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_COLOR_HPP
+#define GCN_COLOR_HPP
+
+#include <iostream>
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ /**
+ * Represents a color with red, green, blue and alpha components.
+ */
+ class Color final
+ {
+ public:
+ /**
+ * Constructor. Initializes the color to black.
+ */
+ Color();
+
+ /**
+ * Constructor. Constructs a color from the bytes in an integer.
+ * Call it with a hexadecimal constant for HTML-style color representation.
+ * The alpha component is 255 by default.
+ *
+ * EXAMPLE: Color(0xff50a0) constructs a very nice pinkish color.
+ *
+ * NOTE: Because of this constructor, integers will be automatically
+ * casted to a color by your compiler.
+ *
+ * @param color The color to initialise the object with.
+ */
+ explicit Color(const int color);
+
+ /**
+ * Constructor. The default alpha value is 255.
+ *
+ * @param r Red color component (range 0-255).
+ * @param g Green color component (range 0-255).
+ * @param b Blue color component (range 0-255).
+ * @param a Alpha, used for transparency. A value of 0 means
+ * totaly transparent, 255 is totaly opaque.
+ */
+ Color(const int r, const int g, const int b, const int a = 255);
+
+ /**
+ * Adds the RGB values of two colors together. The values will be
+ * clamped if they go out of range.
+ *
+ * WARNING: This function will reset the alpha value of the
+ * returned color to 255.
+ *
+ * @param color A color to add to this color.
+ * @return The added colors with an alpha value set to 255.
+ */
+ Color operator+(const Color& color) const;
+
+ /**
+ * Subtracts the RGB values of one color from another.
+ * The values will be clamped if they go out of range.
+ *
+ * WARNING: This function will reset the alpha value of the
+ * returned color to 255.
+ *
+ * @param color A color to subtract from this color.
+ * @return The subtracted colors with an alpha value set to 255.
+ */
+ Color operator-(const Color& color) const;
+
+ /**
+ * Multiplies the RGB values of a color with a float value.
+ * The values will be clamped if they go out of range.
+ *
+ * @param value The value to multiply the color with.
+ * @return The multiplied colors. The alpha value will, unlike
+ * the add and subtract operations, be multiplied as
+ * well.
+ */
+ Color operator*(const float value) const;
+
+ /**
+ * Compares two colors.
+ *
+ * @return True if the two colors have the same RGBA components
+ * false otherwise.
+ */
+ bool operator==(const Color& color) const;
+
+ /**
+ * Compares two colors.
+ *
+ * @return True if the two colors have different RGBA components,
+ * false otherwise.
+ */
+ bool operator!=(const Color& color) const;
+
+ /**
+ * Output operator for output.
+ *
+ * @param out The stream to output to.
+ * @param color The color to output.
+ */
+ friend std::ostream& operator<<(std::ostream& out,
+ const Color& Color);
+
+ /**
+ * Holds the red color component (range 0-255).
+ */
+ int r;
+
+ /**
+ * Holds the green color component (range 0-255).
+ */
+ int g;
+
+ /**
+ * Holds the blue color component (range 0-255).
+ */
+ int b;
+
+ /**
+ * Holds the alpha color component. A value of 0 means totally
+ * transparent while a value of 255 is considered opaque.
+ */
+ int a;
+ };
+} // namespace gcn
+
+#endif // end GCN_COLOR_HPP
diff --git a/src/gui/base/deathlistener.hpp b/src/gui/base/deathlistener.hpp
new file mode 100644
index 000000000..b325166c2
--- /dev/null
+++ b/src/gui/base/deathlistener.hpp
@@ -0,0 +1,109 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_DEATHLISTENER_HPP
+#define GCN_DEATHLISTENER_HPP
+
+#include <string>
+
+#include "gui/base/event.hpp"
+
+namespace gcn
+{
+ /**
+ * Interface for listening for death events from widgets.
+ *
+ * @see Widget::addDeathListener, Widget::removeDeathListener
+ * @author Olof Naessén
+ * @since 0.6.0
+ */
+ class DeathListener
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~DeathListener()
+ { }
+
+ /**
+ * Called when a widget dies. It is used to be able to recieve
+ * a notification when a death of a widget occurs.
+ *
+ * @param event The event of the death.
+ */
+ virtual void death(const Event& event) = 0;
+
+ protected:
+ /**
+ * Constructor.
+ *
+ * You should not be able to make an instance of DeathListener,
+ * therefore its constructor is protected.
+ */
+ DeathListener()
+ { }
+ };
+} // namespace gcn
+
+#endif // end GCN_DEATHLISTENER_HPP
diff --git a/src/gui/base/event.cpp b/src/gui/base/event.cpp
new file mode 100644
index 000000000..359b780bf
--- /dev/null
+++ b/src/gui/base/event.cpp
@@ -0,0 +1,87 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/event.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Event::Event(Widget *const source) :
+ mSource(source)
+ {
+ }
+
+ Event::~Event()
+ {
+ }
+
+ Widget* Event::getSource() const
+ {
+ return mSource;
+ }
+} // namespace gcn
diff --git a/src/gui/base/event.hpp b/src/gui/base/event.hpp
new file mode 100644
index 000000000..2a1f4ca4b
--- /dev/null
+++ b/src/gui/base/event.hpp
@@ -0,0 +1,113 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_EVENT_HPP
+#define GCN_EVENT_HPP
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ class Widget;
+
+ /**
+ * Base class for all events. All events in Guichan should
+ * inherit from this class.
+ *
+ * @author Olof Naessén
+ * @since 0.6.0
+ */
+ class Event
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param source The source widget of the event.
+ */
+ explicit Event(Widget *const source);
+
+ A_DELETE_COPY(Event)
+
+ /**
+ * Destructor.
+ */
+ virtual ~Event();
+
+ /**
+ * Gets the source widget of the event. The function
+ * is used to tell which widget fired an event.
+ *
+ * @return The source widget of the event.
+ */
+ Widget* getSource() const A_WARN_UNUSED;
+
+ protected:
+ /**
+ * Holds the source widget of the event.
+ */
+ Widget* mSource;
+ };
+} // namespace gcn
+
+#endif // end GCN_EVENT_HPP
diff --git a/src/gui/base/exception.cpp b/src/gui/base/exception.cpp
new file mode 100644
index 000000000..998db928d
--- /dev/null
+++ b/src/gui/base/exception.cpp
@@ -0,0 +1,120 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/exception.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Exception::Exception()
+ : mFunction("?"),
+ mMessage(""),
+ mFilename("?"),
+ mLine(0)
+ {
+ }
+
+ Exception::Exception(const std::string& message)
+ : mFunction("?"),
+ mMessage(message),
+ mFilename("?"),
+ mLine(0)
+ {
+ }
+
+ Exception::Exception(const std::string& message,
+ const std::string& function,
+ const std::string& filename,
+ const unsigned int line)
+ : mFunction(function),
+ mMessage(message),
+ mFilename(filename),
+ mLine(line)
+ {
+ }
+
+ const std::string& Exception::getFunction() const
+ {
+ return mFunction;
+ }
+
+ const std::string& Exception::getMessage() const
+ {
+ return mMessage;
+ }
+
+ const std::string& Exception::getFilename() const
+ {
+ return mFilename;
+ }
+
+ unsigned int Exception::getLine() const
+ {
+ return mLine;
+ }
+} // namespace gcn
diff --git a/src/gui/base/exception.hpp b/src/gui/base/exception.hpp
new file mode 100644
index 000000000..a60152c96
--- /dev/null
+++ b/src/gui/base/exception.hpp
@@ -0,0 +1,196 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_EXCEPTION_HPP
+#define GCN_EXCEPTION_HPP
+
+#include <string>
+
+#include "localconsts.h"
+
+#ifndef __FUNCTION__
+#define __FUNCTION__ "?"
+#endif
+
+/*
+ * A macro used to create a standard exception object.
+ * What it basicly does is that it creates a new exception
+ * and automatically sets the filename and line number where
+ * the exception occured by using other compiler macros.
+ */
+#define GCN_EXCEPTION(mess) gcn::Exception(mess, \
+ __FUNCTION__, \
+ __FILE__, \
+ __LINE__)
+
+namespace gcn
+{
+
+ /**
+ * An exception containing a message, a file and a line number
+ * where the exception occured. Guichan will only throw exceptions
+ * of this class.
+ *
+ * You can use this class for your own exceptions that has
+ * something to do with a GUI exception. A nifty feature of the
+ * excpetion class is that it can tell you from which line and
+ * file it was thrown. To make things easier when throwing
+ * exceptions there exists a macro for creating exceptions
+ * which automatically sets the filename and line number.
+ *
+ * EXAMPLE: @code
+ * throw GCN_EXCEPTION("my error message");
+ * @endcode
+ */
+ class Exception final
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ Exception();
+
+ /**
+ * Constructor.
+ *
+ * @param message The error message of the exception.
+ */
+ explicit Exception(const std::string& message);
+
+ /**
+ * Constructor.
+ *
+ * NOTE: Don't use this constructor. Use the GCN_EXCEPTION macro instead.
+ * This constructor merely exists for the GCN_EXCEPTION macro to
+ * use.
+ *
+ * @param message The error message of the exception.
+ * @param function The function name where the exception occured.
+ * @param filename The name of the file where the exception occured.
+ * @param line The line number in the source code where the exception
+ * occured.
+ */
+ Exception(const std::string& message,
+ const std::string& function,
+ const std::string& filename,
+ const unsigned int line);
+
+ /**
+ * Gets the function name where the exception occured.
+ *
+ * @return The function name where the exception occured.
+ */
+ const std::string& getFunction() const A_WARN_UNUSED;
+
+ /**
+ * Gets the error message of the exception.
+ *
+ * @return The error message of the exception.
+ */
+ const std::string& getMessage() const A_WARN_UNUSED;
+
+ /**
+ * Gets the filename where the exception occured.
+ *
+ * @return The filename where the exception occured.
+ */
+ const std::string& getFilename() const A_WARN_UNUSED;
+
+ /**
+ * Gets the line number where the exception occured.
+ *
+ * @return The line number where the exception occured.
+ */
+ unsigned int getLine() const A_WARN_UNUSED;
+
+ protected:
+ /**
+ * Holds the name of the function name where the
+ * exception occured.
+ */
+ std::string mFunction;
+
+ /**
+ * Holds the error message of the exception.
+ */
+ std::string mMessage;
+
+ /**
+ * Holds the filename where the exception occured.
+ */
+ std::string mFilename;
+
+ /**
+ * Holds the line number where the exception occured.
+ */
+ unsigned int mLine;
+ };
+} // namespace gcn
+
+#endif // end GCN_EXCEPTION_HPP
+
+/*
+ * "Final Fantasy XI is the BEST!... It's even better then water!"
+ * - Astrolite
+ * I believe it's WoW now days.
+ */
diff --git a/src/gui/base/focushandler.cpp b/src/gui/base/focushandler.cpp
new file mode 100644
index 000000000..6984d1fcd
--- /dev/null
+++ b/src/gui/base/focushandler.cpp
@@ -0,0 +1,571 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/focushandler.hpp"
+
+#include "gui/base/focuslistener.hpp"
+#include "gui/base/exception.hpp"
+#include "gui/base/widget.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ FocusHandler::FocusHandler() :
+ mWidgets(),
+ mFocusedWidget(nullptr),
+ mModalFocusedWidget(nullptr),
+ mModalMouseInputFocusedWidget(nullptr),
+ mDraggedWidget(nullptr),
+ mLastWidgetWithMouse(nullptr),
+ mLastWidgetWithModalFocus(nullptr),
+ mLastWidgetWithModalMouseInputFocus(nullptr),
+ mLastWidgetPressed(nullptr)
+ {
+ }
+
+ void FocusHandler::requestFocus(Widget* widget)
+ {
+ if (!widget || widget == mFocusedWidget)
+ return;
+
+ int toBeFocusedIndex = -1;
+ for (unsigned int i = 0, sz = static_cast<unsigned int>(
+ mWidgets.size()); i < sz; ++i)
+ {
+ if (mWidgets[i] == widget)
+ {
+ toBeFocusedIndex = i;
+ break;
+ }
+ }
+
+ if (toBeFocusedIndex < 0)
+ throw GCN_EXCEPTION("Trying to focus a none existing widget.");
+
+ Widget *const oldFocused = mFocusedWidget;
+
+ if (oldFocused != widget)
+ {
+ mFocusedWidget = mWidgets.at(toBeFocusedIndex);
+
+ if (oldFocused)
+ {
+ Event focusEvent(oldFocused);
+ distributeFocusLostEvent(focusEvent);
+ }
+
+ Event focusEvent(mWidgets.at(toBeFocusedIndex));
+ distributeFocusGainedEvent(focusEvent);
+ }
+ }
+
+ void FocusHandler::requestModalFocus(Widget* widget)
+ {
+ if (mModalFocusedWidget && mModalFocusedWidget != widget)
+ throw GCN_EXCEPTION("Another widget already has modal focus.");
+
+ mModalFocusedWidget = widget;
+
+ if (mFocusedWidget && !mFocusedWidget->isModalFocused())
+ focusNone();
+ }
+
+ void FocusHandler::requestModalMouseInputFocus(Widget* widget)
+ {
+ if (mModalMouseInputFocusedWidget
+ && mModalMouseInputFocusedWidget != widget)
+ {
+ throw GCN_EXCEPTION("Another widget already has "
+ "modal input focus.");
+ }
+
+ mModalMouseInputFocusedWidget = widget;
+ }
+
+ void FocusHandler::releaseModalFocus(Widget* widget)
+ {
+ if (mModalFocusedWidget == widget)
+ mModalFocusedWidget = nullptr;
+ }
+
+ void FocusHandler::releaseModalMouseInputFocus(Widget* widget)
+ {
+ if (mModalMouseInputFocusedWidget == widget)
+ mModalMouseInputFocusedWidget = nullptr;
+ }
+
+ Widget* FocusHandler::getFocused() const
+ {
+ return mFocusedWidget;
+ }
+
+ Widget* FocusHandler::getModalFocused() const
+ {
+ return mModalFocusedWidget;
+ }
+
+ Widget* FocusHandler::getModalMouseInputFocused() const
+ {
+ return mModalMouseInputFocusedWidget;
+ }
+
+ void FocusHandler::focusNext()
+ {
+ int i;
+ int focusedWidget = -1;
+ const int sz = static_cast<int>(mWidgets.size());
+ for (i = 0; i < sz; ++i)
+ {
+ if (mWidgets[i] == mFocusedWidget)
+ focusedWidget = i;
+ }
+ const int focused = focusedWidget;
+
+ // i is a counter that ensures that the following loop
+ // won't get stuck in an infinite loop
+ i = sz;
+ do
+ {
+ ++ focusedWidget;
+
+ if (i == 0)
+ {
+ focusedWidget = -1;
+ break;
+ }
+
+ -- i;
+
+ if (focusedWidget >= sz)
+ focusedWidget = 0;
+
+ if (focusedWidget == focused)
+ return;
+ }
+ while (!mWidgets.at(focusedWidget)->isFocusable());
+
+ if (focusedWidget >= 0)
+ {
+ mFocusedWidget = mWidgets.at(focusedWidget);
+
+ Event focusEvent(mFocusedWidget);
+ distributeFocusGainedEvent(focusEvent);
+ }
+
+ if (focused >= 0)
+ {
+ Event focusEvent(mWidgets.at(focused));
+ distributeFocusLostEvent(focusEvent);
+ }
+ }
+
+ void FocusHandler::focusPrevious()
+ {
+ if (mWidgets.empty())
+ {
+ mFocusedWidget = nullptr;
+ return;
+ }
+
+ int i;
+ int focusedWidget = -1;
+ const int sz = static_cast<int>(mWidgets.size());
+ for (i = 0; i < sz; ++ i)
+ {
+ if (mWidgets[i] == mFocusedWidget)
+ focusedWidget = i;
+ }
+ const int focused = focusedWidget;
+
+ // i is a counter that ensures that the following loop
+ // won't get stuck in an infinite loop
+ i = sz;
+ do
+ {
+ -- focusedWidget;
+
+ if (i == 0)
+ {
+ focusedWidget = -1;
+ break;
+ }
+
+ -- i;
+
+ if (focusedWidget <= 0)
+ focusedWidget = sz - 1;
+
+ if (focusedWidget == focused)
+ return;
+ }
+ while (!mWidgets.at(focusedWidget)->isFocusable());
+
+ if (focusedWidget >= 0)
+ {
+ mFocusedWidget = mWidgets.at(focusedWidget);
+ Event focusEvent(mFocusedWidget);
+ distributeFocusGainedEvent(focusEvent);
+ }
+
+ if (focused >= 0)
+ {
+ Event focusEvent(mWidgets.at(focused));
+ distributeFocusLostEvent(focusEvent);
+ }
+ }
+
+ bool FocusHandler::isFocused(const Widget* widget) const
+ {
+ return mFocusedWidget == widget;
+ }
+
+ void FocusHandler::add(Widget* widget)
+ {
+ mWidgets.push_back(widget);
+ }
+
+ void FocusHandler::remove(Widget* widget)
+ {
+ if (isFocused(widget))
+ mFocusedWidget = nullptr;
+
+ for (WidgetIterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++iter)
+ {
+ if ((*iter) == widget)
+ {
+ mWidgets.erase(iter);
+ break;
+ }
+ }
+
+ if (mDraggedWidget == widget)
+ {
+ mDraggedWidget = nullptr;
+ return;
+ }
+
+ if (mLastWidgetWithMouse == widget)
+ {
+ mLastWidgetWithMouse = nullptr;
+ return;
+ }
+
+ if (mLastWidgetWithModalFocus == widget)
+ {
+ mLastWidgetWithModalFocus = nullptr;
+ return;
+ }
+
+ if (mLastWidgetWithModalMouseInputFocus == widget)
+ {
+ mLastWidgetWithModalMouseInputFocus = nullptr;
+ return;
+ }
+
+ if (mLastWidgetPressed == widget)
+ {
+ mLastWidgetPressed = nullptr;
+ return;
+ }
+ }
+
+ void FocusHandler::focusNone()
+ {
+ if (mFocusedWidget)
+ {
+ Widget *const focused = mFocusedWidget;
+ mFocusedWidget = nullptr;
+
+ Event focusEvent(focused);
+ distributeFocusLostEvent(focusEvent);
+ }
+ }
+
+ void FocusHandler::tabNext()
+ {
+ if (mFocusedWidget)
+ {
+ if (!mFocusedWidget->isTabOutEnabled())
+ return;
+ }
+
+ if (mWidgets.empty())
+ {
+ mFocusedWidget = nullptr;
+ return;
+ }
+
+ int i;
+ int focusedWidget = -1;
+ const int sz = static_cast<int>(mWidgets.size());
+ for (i = 0; i < sz; ++ i)
+ {
+ if (mWidgets[i] == mFocusedWidget)
+ focusedWidget = i;
+ }
+ const int focused = focusedWidget;
+ bool done = false;
+
+ // i is a counter that ensures that the following loop
+ // won't get stuck in an infinite loop
+ i = sz;
+ do
+ {
+ ++ focusedWidget;
+
+ if (i == 0)
+ {
+ focusedWidget = -1;
+ break;
+ }
+
+ -- i;
+
+ if (focusedWidget >= sz)
+ focusedWidget = 0;
+
+ if (focusedWidget == focused)
+ return;
+
+ const Widget *const widget = mWidgets.at(focusedWidget);
+ if (widget->isFocusable() && widget->isTabInEnabled() &&
+ (!mModalFocusedWidget || widget->isModalFocused()))
+ {
+ done = true;
+ }
+ }
+ while (!done);
+
+ if (focusedWidget >= 0)
+ {
+ mFocusedWidget = mWidgets.at(focusedWidget);
+ Event focusEvent(mFocusedWidget);
+ distributeFocusGainedEvent(focusEvent);
+ }
+
+ if (focused >= 0)
+ {
+ Event focusEvent(mWidgets.at(focused));
+ distributeFocusLostEvent(focusEvent);
+ }
+ }
+
+ void FocusHandler::tabPrevious()
+ {
+ if (mFocusedWidget)
+ {
+ if (!mFocusedWidget->isTabOutEnabled())
+ return;
+ }
+
+ if (mWidgets.empty())
+ {
+ mFocusedWidget = nullptr;
+ return;
+ }
+
+ int i;
+ int focusedWidget = -1;
+ const int sz = static_cast<int>(mWidgets.size());
+ for (i = 0; i < sz; ++ i)
+ {
+ if (mWidgets[i] == mFocusedWidget)
+ focusedWidget = i;
+ }
+ const int focused = focusedWidget;
+ bool done = false;
+
+ // i is a counter that ensures that the following loop
+ // won't get stuck in an infinite loop
+ i = sz;
+ do
+ {
+ -- focusedWidget;
+
+ if (i == 0)
+ {
+ focusedWidget = -1;
+ break;
+ }
+
+ -- i;
+
+ if (focusedWidget <= 0)
+ focusedWidget = sz - 1;
+
+ if (focusedWidget == focused)
+ return;
+
+ const Widget *const widget = mWidgets.at(focusedWidget);
+ if (widget->isFocusable() && widget->isTabInEnabled() &&
+ (!mModalFocusedWidget || widget->isModalFocused()))
+ {
+ done = true;
+ }
+ }
+ while (!done);
+
+ if (focusedWidget >= 0)
+ {
+ mFocusedWidget = mWidgets.at(focusedWidget);
+ Event focusEvent(mFocusedWidget);
+ distributeFocusGainedEvent(focusEvent);
+ }
+
+ if (focused >= 0)
+ {
+ Event focusEvent(mWidgets.at(focused));
+ distributeFocusLostEvent(focusEvent);
+ }
+ }
+
+ void FocusHandler::distributeFocusLostEvent(const Event& focusEvent)
+ {
+ Widget *const sourceWidget = focusEvent.getSource();
+
+ std::list<FocusListener*> focusListeners
+ = sourceWidget->_getFocusListeners();
+
+ // Send the event to all focus listeners of the widget.
+ for (std::list<FocusListener*>::const_iterator
+ it = focusListeners.begin();
+ it != focusListeners.end();
+ ++ it)
+ {
+ (*it)->focusLost(focusEvent);
+ }
+ }
+
+ void FocusHandler::distributeFocusGainedEvent(const Event& focusEvent)
+ {
+ Widget *const sourceWidget = focusEvent.getSource();
+
+ std::list<FocusListener*> focusListeners
+ = sourceWidget->_getFocusListeners();
+
+ // Send the event to all focus listeners of the widget.
+ for (std::list<FocusListener*>::const_iterator
+ it = focusListeners.begin();
+ it != focusListeners.end();
+ ++ it)
+ {
+ (*it)->focusGained(focusEvent);
+ }
+ }
+
+ Widget* FocusHandler::getDraggedWidget()
+ {
+ return mDraggedWidget;
+ }
+
+ void FocusHandler::setDraggedWidget(Widget* draggedWidget)
+ {
+ mDraggedWidget = draggedWidget;
+ }
+
+ Widget* FocusHandler::getLastWidgetWithMouse()
+ {
+ return mLastWidgetWithMouse;
+ }
+
+ void FocusHandler::setLastWidgetWithMouse(Widget* lastWidgetWithMouse)
+ {
+ mLastWidgetWithMouse = lastWidgetWithMouse;
+ }
+
+ Widget* FocusHandler::getLastWidgetWithModalFocus()
+ {
+ return mLastWidgetWithModalFocus;
+ }
+
+ void FocusHandler::setLastWidgetWithModalFocus(Widget* widget)
+ {
+ mLastWidgetWithModalFocus = widget;
+ }
+
+ Widget* FocusHandler::getLastWidgetWithModalMouseInputFocus()
+ {
+ return mLastWidgetWithModalMouseInputFocus;
+ }
+
+ void FocusHandler::setLastWidgetWithModalMouseInputFocus(Widget* widget)
+ {
+ mLastWidgetWithModalMouseInputFocus = widget;
+ }
+
+ Widget* FocusHandler::getLastWidgetPressed()
+ {
+ return mLastWidgetPressed;
+ }
+
+ void FocusHandler::setLastWidgetPressed(Widget* lastWidgetPressed)
+ {
+ mLastWidgetPressed = lastWidgetPressed;
+ }
+} // namespace gcn
diff --git a/src/gui/base/focushandler.hpp b/src/gui/base/focushandler.hpp
new file mode 100644
index 000000000..aab3f2464
--- /dev/null
+++ b/src/gui/base/focushandler.hpp
@@ -0,0 +1,417 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_FOCUSHANDLER_HPP
+#define GCN_FOCUSHANDLER_HPP
+
+#include <vector>
+
+#include "gui/base/event.hpp"
+
+namespace gcn
+{
+ class Widget;
+
+ /**
+ * Handles focus for widgets in a Gui. Each Gui has at least one
+ * focus handler.
+ * You will probably not use the focus handler directly as Widget
+ * has functions that automatically uses the active focus handler.
+ *
+ * @see Widget::isFocus, Widget::isModalFocused,
+ * Widget::isModalMouseInputFocused, Widget::requestFocus,
+ * Widget::requestModalFocus, Widget::requestModalMouseInputFocus,
+ * Widget::releaseModalFocus, Widget::relaseModalMouseInputFocus,
+ * Widget::setFocusable, Widget::isFocusable, FocusListener
+ *
+ * @since 0.1.0
+ */
+ class FocusHandler
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ FocusHandler();
+
+ A_DELETE_COPY(FocusHandler)
+
+ /**
+ * Destructor.
+ */
+ virtual ~FocusHandler()
+ { }
+
+ /**
+ * Requests focus for a widget. Focus will only be granted to a widget
+ * if it's focusable and if no other widget has modal focus.
+ * If a widget receives focus a focus event will be sent to the
+ * focus listeners of the widget.
+ *
+ * @param widget The widget to request focus for.
+ * @see isFocused, Widget::requestFocus
+ */
+ virtual void requestFocus(Widget* widget);
+
+ /**
+ * Requests modal focus for a widget. Focus will only be granted
+ * to a widget if it's focusable and if no other widget has modal
+ * focus.
+ *
+ * @param widget The widget to request modal focus for.
+ * @throws Exception when another widget already has modal focus.
+ * @see releaseModalFocus, Widget::requestModalFocus
+ */
+ virtual void requestModalFocus(Widget* widget);
+
+ /**
+ * Requests modal mouse input focus for a widget. Focus will only
+ * be granted to a widget if it's focusable and if no other widget
+ * has modal mouse input focus.
+ *
+ * Modal mouse input focus means no other widget then the widget with
+ * modal mouse input focus will receive mouse input. The widget with
+ * modal mouse input focus will also receive mouse input no matter what
+ * the mouse input is or where the mouse input occurs.
+ *
+ * @param widget The widget to focus for modal mouse input focus.
+ * @throws Exception when another widget already has modal mouse input
+ * focus.
+ * @see releaseModalMouseInputFocus, Widget::requestModalMouseInputFocus
+ */
+ virtual void requestModalMouseInputFocus(Widget* widget);
+
+ /**
+ * Releases modal focus if the widget has modal focus.
+ * If the widget doesn't have modal focus no relase will occur.
+ *
+ * @param widget The widget to release modal focus for.
+ * @see reuqestModalFocus, Widget::releaseModalFocus
+ */
+ virtual void releaseModalFocus(Widget* widget);
+
+ /**
+ * Releases modal mouse input focus if the widget has modal mouse input
+ * focus. If the widget doesn't have modal mouse input focus no relase
+ * will occur.
+ *
+ * @param widget the widget to release modal mouse input focus for.
+ * @see requestModalMouseInputFocus, Widget::releaseModalMouseInputFocus
+ */
+ virtual void releaseModalMouseInputFocus(Widget* widget);
+
+ /**
+ * Checks if a widget is focused.
+ *
+ * @param widget The widget to check.
+ * @return True if the widget is focused, false otherwise.
+ * @see Widget::isFocused
+ */
+ virtual bool isFocused(const Widget* widget) const;
+
+ /**
+ * Gets the widget with focus.
+ *
+ * @return The widget with focus. NULL if no widget has focus.
+ */
+ virtual Widget* getFocused() const A_WARN_UNUSED;
+
+ /**
+ * Gets the widget with modal focus.
+ *
+ * @return The widget with modal focus. NULL if no widget has
+ * modal focus.
+ */
+ virtual Widget* getModalFocused() const A_WARN_UNUSED;
+
+ /**
+ * Gets the widget with modal mouse input focus.
+ *
+ * @return The widget with modal mouse input focus. NULL if
+ * no widget has modal mouse input focus.
+ */
+ virtual Widget* getModalMouseInputFocused() const A_WARN_UNUSED;
+
+ /**
+ * Focuses the next widget added to a conainer.
+ * If no widget has focus the first widget gets focus. The order
+ * in which the widgets are focused is determined by the order
+ * they were added to a container.
+ *
+ * @see focusPrevious
+ */
+ virtual void focusNext();
+
+ /**
+ * Focuses the previous widget added to a contaienr.
+ * If no widget has focus the first widget gets focus. The order
+ * in which the widgets are focused is determined by the order
+ * they were added to a container.
+ *
+ * @see focusNext
+ */
+ virtual void focusPrevious();
+
+ /**
+ * Adds a widget to by handles by the focus handler.
+ *
+ * @param widget The widget to add.
+ * @see remove
+ */
+ virtual void add(Widget* widget);
+
+ /**
+ * Removes a widget from the focus handler.
+ *
+ * @param widget The widget to remove.
+ * @see add
+ */
+ virtual void remove(Widget* widget);
+
+ /**
+ * Focuses nothing. A focus event will also be sent to the
+ * focused widget's focus listeners if a widget has focus.
+ */
+ virtual void focusNone();
+
+ /**
+ * Focuses the next widget which allows tabbing in unless
+ * the current focused Widget disallows tabbing out.
+ *
+ * @see tabPrevious
+ */
+ virtual void tabNext();
+
+ /**
+ * Focuses the previous widget which allows tabbing in unless
+ * current focused widget disallows tabbing out.
+ *
+ * @see tabNext
+ */
+ virtual void tabPrevious();
+
+ /**
+ * Gets the widget being dragged. Used by the Gui class to
+ * keep track of the dragged widget.
+ *
+ * @return the widget being dragged.
+ * @see setDraggedWidget
+ */
+ virtual Widget* getDraggedWidget() A_WARN_UNUSED;
+
+ /**
+ * Sets the widget being dragged. Used by the Gui class to
+ * keep track of the dragged widget.
+ *
+ * @param draggedWidget The widget being dragged.
+ * @see getDraggedWidget
+ */
+ virtual void setDraggedWidget(Widget* draggedWidget);
+
+ /**
+ * Gets the last widget with the mouse. Used by the Gui class
+ * to keep track the last widget with the mouse.
+ *
+ * @return The last widget with the mouse.
+ * @see setLastWidgetWithMouse
+ */
+ virtual Widget* getLastWidgetWithMouse() A_WARN_UNUSED;
+
+ /**
+ * Sets the last widget with the mouse. Used by the Gui class
+ * to keep track the last widget with the mouse.
+ *
+ * @param lastWidgetWithMouse The last widget with the mouse.
+ * @see getLastWidgetWithMouse
+ */
+ virtual void setLastWidgetWithMouse(Widget* lastWidgetWithMouse);
+
+ /**
+ * Gets the last widget with modal focus.
+ *
+ * @return The last widget with modal focus.
+ * @see setLastWidgetWithModalFocus
+ */
+ virtual Widget* getLastWidgetWithModalFocus() A_WARN_UNUSED;
+
+ /**
+ * Sets the last widget with modal focus.
+ *
+ * @param widget The last widget with modal focus.
+ * @see getLastWidgetWithModalFocus
+ */
+ virtual void setLastWidgetWithModalFocus(Widget* widget);
+
+ /**
+ * Gets the last widget with modal mouse input focus.
+ *
+ * @return The last widget with modal mouse input focus.
+ * @see setLastWidgetWithModalMouseInputFocus
+ */
+ virtual Widget* getLastWidgetWithModalMouseInputFocus() A_WARN_UNUSED;
+
+ /**
+ * Sets the last widget with modal mouse input focus.
+ *
+ * @param widget The last widget with modal mouse input focus.
+ * @see getLastWidgetWithModalMouseInputFocus
+ */
+ virtual void setLastWidgetWithModalMouseInputFocus(Widget* widget);
+
+ /**
+ * Gets the last widget pressed. Used by the Gui class to keep track
+ * of pressed widgets.
+ *
+ * @return The last widget pressed.
+ * @see setLastWidgetPressed
+ */
+ virtual Widget* getLastWidgetPressed() A_WARN_UNUSED;
+
+ /**
+ * Sets the last widget pressed. Used by the Gui class to keep track
+ * of pressed widgets.
+ *
+ * @param lastWidgetPressed The last widget pressed.
+ * @see getLastWidgetPressed
+ */
+ virtual void setLastWidgetPressed(Widget* lastWidgetPressed);
+
+ protected:
+ /**
+ * Distributes a focus lost event.
+ *
+ * @param focusEvent the event to distribute.
+ * @since 0.7.0
+ */
+ virtual void distributeFocusLostEvent(const Event& focusEvent);
+
+ /**
+ * Distributes a focus gained event.
+ *
+ * @param focusEvent the event to distribute.
+ * @since 0.7.0
+ */
+ virtual void distributeFocusGainedEvent(const Event& focusEvent);
+
+ /**
+ * Typedef.
+ */
+ typedef std::vector<Widget*> WidgetVector;
+
+ /**
+ * Typedef.
+ */
+ typedef WidgetVector::iterator WidgetIterator;
+
+ /**
+ * Holds the widgets currently being handled by the
+ * focus handler.
+ */
+ WidgetVector mWidgets;
+
+ /**
+ * Holds the focused widget. NULL if no widget has focus.
+ */
+ Widget* mFocusedWidget;
+
+ /**
+ * Holds the modal focused widget. NULL if no widget has
+ * modal focused.
+ */
+ Widget* mModalFocusedWidget;
+
+ /**
+ * Holds the modal mouse input focused widget. NULL if no widget
+ * is being dragged.
+ */
+ Widget* mModalMouseInputFocusedWidget;
+
+ /**
+ * Holds the dragged widget. NULL if no widget is
+ * being dragged.
+ */
+ Widget* mDraggedWidget;
+
+ /**
+ * Holds the last widget with the mouse.
+ */
+ Widget* mLastWidgetWithMouse;
+
+ /**
+ * Holds the last widget with modal focus.
+ */
+ Widget* mLastWidgetWithModalFocus;
+
+ /**
+ * Holds the last widget with modal mouse input focus.
+ */
+ Widget* mLastWidgetWithModalMouseInputFocus;
+
+ /**
+ * Holds the last widget pressed.
+ */
+ Widget* mLastWidgetPressed;
+ };
+} // namespace gcn
+
+#endif // end GCN_FOCUSHANDLER_HPP
diff --git a/src/gui/base/focuslistener.hpp b/src/gui/base/focuslistener.hpp
new file mode 100644
index 000000000..f6a7da5ea
--- /dev/null
+++ b/src/gui/base/focuslistener.hpp
@@ -0,0 +1,119 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_FOCUSLISTENER_HPP
+#define GCN_FOCUSLISTENER_HPP
+
+#include <string>
+
+#include "gui/base/event.hpp"
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ /**
+ * Interface for listening for focus events from widgets.
+ *
+ * @see Widget::addFocusListener, Widget::removeFocusListener
+ * @author Olof Naessén
+ * @since 0.7.0
+ */
+ class FocusListener
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~FocusListener()
+ { }
+
+ /**
+ * Called when a widget gains focus.
+ *
+ * @param event Discribes the event.
+ */
+ virtual void focusGained(const Event& event A_UNUSED)
+ { }
+
+ /**
+ * Called when a widget loses focus.
+ *
+ * @param event Discribes the event.
+ */
+ virtual void focusLost(const Event& event A_UNUSED)
+ { }
+
+ protected:
+ /**
+ * Constructor.
+ *
+ * You should not be able to make an instance of FocusListener,
+ * therefore its constructor is protected.
+ */
+ FocusListener()
+ { }
+ };
+} // namespace gcn
+
+#endif // end GCN_FOCUSLISTENER_HPP
diff --git a/src/gui/base/font.cpp b/src/gui/base/font.cpp
new file mode 100644
index 000000000..ccb2f7022
--- /dev/null
+++ b/src/gui/base/font.cpp
@@ -0,0 +1,87 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/font.hpp"
+
+#include <string>
+
+#include "debug.h"
+
+namespace gcn
+{
+ int Font::getStringIndexAt(const std::string& text, const int x) const
+ {
+ const size_t sz = text.size();
+ for (size_t i = 0; i < sz; ++i)
+ {
+ if (getWidth(text.substr(0, i)) > x)
+ return i;
+ }
+
+ return static_cast<int>(sz);
+ }
+} // namespace gcn
diff --git a/src/gui/base/font.hpp b/src/gui/base/font.hpp
new file mode 100644
index 000000000..8e8ad18c9
--- /dev/null
+++ b/src/gui/base/font.hpp
@@ -0,0 +1,133 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_FONT_HPP
+#define GCN_FONT_HPP
+
+#include <string>
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ class Graphics;
+
+ /**
+ * Interface for a font.
+ *
+ * @see ImageFont
+ */
+ class Font
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~Font()
+ { }
+
+ /**
+ * Gets the width of a string. The width of a string is not necesserily
+ * the sum of all the widths of it's glyphs.
+ *
+ * @param text The string to return the width of.
+ * @return The width of a string.
+ */
+ virtual int getWidth(const std::string& text) const A_WARN_UNUSED = 0;
+
+ /**
+ * Gets the height of the glyphs in the font.
+ *
+ * @return The height of the glyphs int the font.
+ */
+ virtual int getHeight() const A_WARN_UNUSED = 0;
+
+ /**
+ * Gets a string index in a string providing an x coordinate.
+ * Used to retrive a string index (for a character in a
+ * string) at a certain x position. It is especially useful
+ * when a mouse clicks in a TextField and you want to know which
+ * character was clicked.
+ *
+ * @return A string index in a string providing an x coordinate.
+ */
+ virtual int getStringIndexAt(const std::string& text,
+ const int x) const A_WARN_UNUSED;
+
+ /**
+ * Draws a string.
+ *
+ * NOTE: You normally won't use this function to draw text since
+ * Graphics contains better functions for drawing text.
+ *
+ * @param graphics A Graphics object to use for drawing.
+ * @param text The string to draw.
+ * @param x The x coordinate where to draw the string.
+ * @param y The y coordinate where to draw the string.
+ */
+ virtual void drawString(Graphics* graphics, const std::string& text,
+ int x, int y) = 0;
+ };
+} // namespace gcn
+
+#endif // end GCN_FONT_HPP
diff --git a/src/gui/base/graphics.cpp b/src/gui/base/graphics.cpp
new file mode 100644
index 000000000..229543bc9
--- /dev/null
+++ b/src/gui/base/graphics.cpp
@@ -0,0 +1,179 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/graphics.hpp"
+
+#include "gui/base/exception.hpp"
+#include "gui/base/font.hpp"
+#include "gui/base/image.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+
+ Graphics::Graphics() :
+ mClipStack(),
+ mFont(nullptr)
+ {
+ }
+
+ bool Graphics::pushClipArea(Rectangle area)
+ {
+ // Ignore area with a negate width or height
+ // by simple pushing an empty clip area
+ // to the stack.
+ if (area.width < 0 || area.height < 0)
+ {
+ ClipRectangle carea;
+ mClipStack.push(carea);
+ return true;
+ }
+
+ if (mClipStack.empty())
+ {
+ ClipRectangle carea;
+ carea.x = area.x;
+ carea.y = area.y;
+ carea.width = area.width;
+ carea.height = area.height;
+ carea.xOffset = area.x;
+ carea.yOffset = area.y;
+ mClipStack.push(carea);
+ return true;
+ }
+
+ const ClipRectangle &top = mClipStack.top();
+ ClipRectangle carea;
+ carea = area;
+ carea.xOffset = top.xOffset + carea.x;
+ carea.yOffset = top.yOffset + carea.y;
+ carea.x += top.xOffset;
+ carea.y += top.yOffset;
+
+ // Clamp the pushed clip rectangle.
+ if (carea.x < top.x)
+ carea.x = top.x;
+
+ if (carea.y < top.y)
+ carea.y = top.y;
+
+ if (carea.x + carea.width > top.x + top.width)
+ {
+ carea.width = top.x + top.width - carea.x;
+
+ if (carea.width < 0)
+ carea.width = 0;
+ }
+
+ if (carea.y + carea.height > top.y + top.height)
+ {
+ carea.height = top.y + top.height - carea.y;
+
+ if (carea.height < 0)
+ carea.height = 0;
+ }
+
+ const bool result = carea.isIntersecting(top);
+
+ mClipStack.push(carea);
+
+ return result;
+ }
+
+ void Graphics::popClipArea()
+ {
+ if (mClipStack.empty())
+ throw GCN_EXCEPTION("Tried to pop clip area from empty stack.");
+
+ mClipStack.pop();
+ }
+
+ const ClipRectangle& Graphics::getCurrentClipArea()
+ {
+ if (mClipStack.empty())
+ throw GCN_EXCEPTION("The clip area stack is empty.");
+
+ return mClipStack.top();
+ }
+
+ void Graphics::drawImage(const Image* image A_UNUSED,
+ int dstX A_UNUSED, int dstY A_UNUSED)
+ {
+ }
+
+/*
+ void Graphics::setFont(Font* font)
+ {
+ }
+
+ void Graphics::drawText(const std::string& text, int x, int y,
+ Alignment alignment)
+ {
+ }
+*/
+} // namespace gcn
diff --git a/src/gui/base/graphics.hpp b/src/gui/base/graphics.hpp
new file mode 100644
index 000000000..d3128c8ae
--- /dev/null
+++ b/src/gui/base/graphics.hpp
@@ -0,0 +1,294 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_GRAPHICS_HPP
+#define GCN_GRAPHICS_HPP
+
+#include <iosfwd>
+#include <stack>
+
+#include "gui/base/cliprectangle.hpp"
+
+namespace gcn
+{
+ class Color;
+ class Font;
+ class Image;
+
+ /**
+ * Abstract class for providing drawing primitve functions.
+ * It contains all vital functions for drawing.
+ *
+ * Guichan contains implementations of Graphics for common
+ * libraries like the Allegro library, the HGE library,
+ * the OpenGL library, the OpenLayer library, and the SDL library.
+ * To make Guichan usable with other libraries, a Graphics class
+ * must be implemented.
+ *
+ * In Graphics you can set clip areas to limit drawing to certain
+ * areas of the screen. Clip areas are put on a stack, which
+ * means that you can push smaller and smaller clip areas onto the
+ * stack. All coordinates will be relative to the top most clip area.
+ * In most cases you won't have to worry about the clip areas,
+ * unless you want to implement some really complex widget.
+ * Pushing and poping of clip areas are handled automatically by
+ * container widgets when their child widgets are drawn.
+ *
+ * IMPORTANT: Remember to pop each clip area that you pushed on the stack
+ * after you are done with it.
+ *
+ * If you feel that Graphics is to restrictive for your needs,
+ * there is no one stopping you from using your own code for drawing
+ * in widgets. You could for instance use pure SDL in the drawing of
+ * widgets bypassing Graphics. This might however hurt portability of
+ * your application.
+ *
+ * If you implement a Graphics class not present in Guichan we would
+ * be very happy to add it to Guichan.
+ *
+ * @see AllegroGraphics, HGEGraphics, OpenLayerGraphics, OpenGLGraphics,
+ * SDLGraphics, Image
+ * @since 0.1.0
+ */
+ class Graphics
+ {
+ public:
+ /**
+ * Alignments for text drawing.
+ */
+ enum Alignment
+ {
+ LEFT = 0,
+ CENTER,
+ RIGHT
+ };
+
+ /**
+ * Constructor.
+ */
+ Graphics();
+
+ A_DELETE_COPY(Graphics)
+
+ /**
+ * Destructor.
+ */
+ virtual ~Graphics()
+ { }
+
+ /**
+ * Initializes drawing. Called by the Gui when Gui::draw() is called.
+ * It is needed by some implementations of Graphics to perform
+ * preparations before drawing. An example of such an implementation
+ * is the OpenGLGraphics.
+ *
+ * NOTE: You will never need to call this function yourself, unless
+ * you use a Graphics object outside of Guichan.
+ *
+ * @see _endDraw, Gui::draw
+ */
+ virtual void _beginDraw()
+ { }
+
+ /**
+ * Deinitializes drawing. Called by the Gui when a Gui::draw() is done.
+ * done. It should reset any state changes made by _beginDraw().
+ *
+ * NOTE: You will never need to call this function yourself, unless
+ * you use a Graphics object outside of Guichan.
+ *
+ * @see _beginDraw, Gui::draw
+ */
+ virtual void _endDraw()
+ { }
+
+ /**
+ * Pushes a clip area onto the stack. The x and y coordinates in the
+ * rectangle is relative to the last pushed clip area.
+ * If the new area falls outside the current clip area, it will be
+ * clipped as necessary.
+ *
+ * If a clip area is outside of the top clip area a clip area with
+ * zero width and height will be pushed.
+ *
+ * @param area The clip area to be pushed onto the stack.
+ * @return False if the the new area lays outside the current clip
+ * area.
+ */
+ virtual bool pushClipArea(Rectangle area);
+
+ /**
+ * Removes the top most clip area from the stack.
+ *
+ * @throws Exception if the stack is empty.
+ */
+ virtual void popClipArea();
+
+ /**
+ * Gets the current clip area. Usefull if you want to do drawing
+ * bypassing Graphics.
+ *
+ * @return The current clip area.
+ */
+ virtual const ClipRectangle& getCurrentClipArea();
+
+ /**
+ * Draws a part of an image.
+ *
+ * NOTE: Width and height arguments will not scale the image but
+ * specifies the size of the part to be drawn. If you want
+ * to draw the whole image there is a simplified version of
+ * this function.
+ *
+ * EXAMPLE: @code drawImage(myImage, 10, 10, 20, 20, 40, 40); @endcode
+ * Will draw a rectangular piece of myImage starting at
+ * coordinate (10, 10) in myImage, with width and height 40.
+ * The piece will be drawn with it's top left corner at
+ * coordinate (20, 20).
+ *
+ * @param image The image to draw.
+ * @param srcX The source image x coordinate.
+ * @param srcY The source image y coordinate.
+ * @param dstX The destination x coordinate.
+ * @param dstY The destination y coordinate.
+ * @param width The width of the piece.
+ * @param height The height of the piece.
+ */
+ virtual void drawImage(const Image* image,
+ int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int width,
+ int height) = 0;
+ /**
+ * Draws an image. A simplified version of the other drawImage.
+ * It will draw a whole image at the coordinate you specify.
+ * It is equivalent to calling:
+ * @code drawImage(myImage, 0, 0, dstX, dstY, image->getWidth(), \
+ image->getHeight()); @endcode
+ */
+ virtual void drawImage(const Image* image, int dstX, int dstY);
+
+ /**
+ * Draws a single point/pixel.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ */
+ virtual void drawPoint(int x, int y) = 0;
+
+ /**
+ * Ddraws a line.
+ *
+ * @param x1 The first x coordinate.
+ * @param y1 The first y coordinate.
+ * @param x2 The second x coordinate.
+ * @param y2 The second y coordinate.
+ */
+ virtual void drawLine(int x1, int y1, int x2, int y2) = 0;
+
+ /**
+ * Draws a simple, non-filled, rectangle with a one pixel width.
+ *
+ * @param rectangle The rectangle to draw.
+ */
+ virtual void drawRectangle(const Rectangle& rectangle) = 0;
+
+ /**
+ * Draws a filled rectangle.
+ *
+ * @param rectangle The filled rectangle to draw.
+ */
+ virtual void fillRectangle(const Rectangle& rectangle) = 0;
+
+ /**
+ * Sets the color to use when drawing.
+ *
+ * @param color A color.
+ * @see getColor
+ */
+ virtual void setColor(const Color& color) = 0;
+
+ /**
+ * Gets the color to use when drawing.
+ *
+ * @return The color used when drawing.
+ * @see setColor
+ */
+ virtual const Color& getColor() const = 0;
+
+ protected:
+ /**
+ * Holds the clip area stack.
+ */
+ std::stack<ClipRectangle> mClipStack;
+
+ /**
+ * Holds the current font.
+ */
+ Font* mFont;
+ };
+} // namespace gcn
+
+#endif // end GCN_GRAPHICS_HPP
diff --git a/src/gui/base/gui.cpp b/src/gui/base/gui.cpp
new file mode 100644
index 000000000..e4827f716
--- /dev/null
+++ b/src/gui/base/gui.cpp
@@ -0,0 +1,765 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/gui.hpp"
+
+#include "gui/base/basiccontainer.hpp"
+#include "gui/base/exception.hpp"
+#include "gui/base/focushandler.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/input.hpp"
+#include "gui/base/keyinput.hpp"
+#include "gui/base/keylistener.hpp"
+#include "gui/base/mouseinput.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widget.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Gui::Gui() :
+ mTop(nullptr),
+ mGraphics(nullptr),
+ mInput(nullptr),
+ mFocusHandler(new FocusHandler),
+ mTabbing(true),
+ mKeyListeners(),
+ mShiftPressed(false),
+ mMetaPressed(false),
+ mControlPressed(false),
+ mAltPressed(false),
+ mLastMousePressButton(0),
+ mLastMousePressTimeStamp(0),
+ mLastMouseX(0),
+ mLastMouseY(0),
+ mClickCount(1),
+ mLastMouseDragButton(0),
+ mWidgetWithMouseQueue()
+ {
+ }
+
+ Gui::~Gui()
+ {
+ if (Widget::widgetExists(mTop))
+ setTop(nullptr);
+
+ delete mFocusHandler;
+ mFocusHandler = nullptr;
+ }
+
+ void Gui::setTop(Widget* top)
+ {
+ if (mTop)
+ mTop->_setFocusHandler(nullptr);
+ if (top)
+ top->_setFocusHandler(mFocusHandler);
+
+ 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()
+ {
+ }
+
+ void Gui::draw()
+ {
+ }
+
+ void Gui::focusNone()
+ {
+ mFocusHandler->focusNone();
+ }
+
+ void Gui::setTabbingEnabled(bool tabbing)
+ {
+ mTabbing = tabbing;
+ }
+
+ bool Gui::isTabbingEnabled()
+ {
+ return mTabbing;
+ }
+
+ void Gui::addGlobalKeyListener(KeyListener* keyListener)
+ {
+ mKeyListeners.push_back(keyListener);
+ }
+
+ void Gui::removeGlobalKeyListener(KeyListener* keyListener)
+ {
+ mKeyListeners.remove(keyListener);
+ }
+
+ void Gui::handleMouseInput()
+ {
+ }
+
+ void Gui::handleKeyInput()
+ {
+ }
+
+ void Gui::handleMouseMoved(const MouseInput& mouseInput)
+ {
+ // Check if the mouse leaves the application window.
+ if (!mWidgetWithMouseQueue.empty() && (mouseInput.getX() < 0
+ || mouseInput.getY() < 0 || !mTop->getDimension().isPointInRect(
+ mouseInput.getX(), mouseInput.getY())))
+ {
+ // Distribute an event to all widgets in the
+ // "widget with mouse" queue.
+ while (!mWidgetWithMouseQueue.empty())
+ {
+ Widget *const widget = mWidgetWithMouseQueue.front();
+
+ if (Widget::widgetExists(widget))
+ {
+ distributeMouseEvent(widget,
+ MouseEvent::EXITED,
+ mouseInput.getButton(),
+ mouseInput.getX(),
+ mouseInput.getY(),
+ true,
+ true);
+ }
+
+ mWidgetWithMouseQueue.pop_front();
+ }
+
+ return;
+ }
+
+ // Check if there is a need to send mouse exited events by
+ // traversing the "widget with mouse" queue.
+ bool widgetWithMouseQueueCheckDone = mWidgetWithMouseQueue.empty();
+ while (!widgetWithMouseQueueCheckDone)
+ {
+ unsigned int iterations = 0;
+ for (std::deque<Widget*>::iterator
+ iter = mWidgetWithMouseQueue.begin();
+ iter != mWidgetWithMouseQueue.end();
+ ++ iter)
+ {
+ Widget *const widget = *iter;
+
+ // If a widget in the "widget with mouse queue" doesn't
+ // exists anymore it should be removed from the queue.
+ if (!Widget::widgetExists(widget))
+ {
+ mWidgetWithMouseQueue.erase(iter);
+ break;
+ }
+ else
+ {
+ int x, y;
+ widget->getAbsolutePosition(x, y);
+
+ if (x > mouseInput.getX()
+ || y > mouseInput.getY()
+ || x + widget->getWidth() <= mouseInput.getX()
+ || y + widget->getHeight() <= mouseInput.getY()
+ || !widget->isVisible())
+ {
+ distributeMouseEvent(widget,
+ MouseEvent::EXITED,
+ mouseInput.getButton(),
+ mouseInput.getX(),
+ mouseInput.getY(),
+ true,
+ true);
+ mClickCount = 1;
+ mLastMousePressTimeStamp = 0;
+ mWidgetWithMouseQueue.erase(iter);
+ break;
+ }
+ }
+
+ iterations++;
+ }
+
+ widgetWithMouseQueueCheckDone =
+ (iterations == mWidgetWithMouseQueue.size());
+ }
+
+ // Check all widgets below the mouse to see if they are
+ // present in the "widget with mouse" queue. If a widget
+ // is not then it should be added and an entered event should
+ // be sent to it.
+ Widget* parent = getMouseEventSource(
+ mouseInput.getX(), mouseInput.getY());
+ Widget* widget = parent;
+
+ // If a widget has modal mouse input focus then it will
+ // always be returned from getMouseEventSource, but we only wan't to
+ // send mouse entered events if the mouse has actually entered the
+ // widget with modal mouse input focus, hence we need to check if
+ // that's the case. If it's not we should simply ignore to send any
+ // mouse entered events.
+ if (mFocusHandler->getModalMouseInputFocused()
+ && widget == mFocusHandler->getModalMouseInputFocused()
+ && Widget::widgetExists(widget))
+ {
+ int x, y;
+ widget->getAbsolutePosition(x, y);
+
+ if (x > mouseInput.getX() || y > mouseInput.getY()
+ || x + widget->getWidth() <= mouseInput.getX()
+ || y + widget->getHeight() <= mouseInput.getY())
+ {
+ parent = nullptr;
+ }
+ }
+
+ while (parent)
+ {
+ parent = widget->getParent();
+
+ // Check if the widget is present in the "widget with mouse" queue.
+ bool widgetIsPresentInQueue = false;
+ FOR_EACH (std::deque<Widget*>::const_iterator,
+ iter, mWidgetWithMouseQueue)
+ {
+ if (*iter == widget)
+ {
+ widgetIsPresentInQueue = true;
+ break;
+ }
+ }
+
+ // Widget is not present, send an entered event and add
+ // it to the "widget with mouse" queue.
+ if (!widgetIsPresentInQueue
+ && Widget::widgetExists(widget))
+ {
+ distributeMouseEvent(widget,
+ MouseEvent::ENTERED,
+ mouseInput.getButton(),
+ mouseInput.getX(),
+ mouseInput.getY(),
+ true,
+ true);
+ mWidgetWithMouseQueue.push_front(widget);
+ }
+
+ const Widget *const swap = widget;
+ widget = parent;
+ parent = swap->getParent();
+ }
+
+ if (mFocusHandler->getDraggedWidget())
+ {
+ distributeMouseEvent(mFocusHandler->getDraggedWidget(),
+ MouseEvent::DRAGGED,
+ mLastMouseDragButton,
+ mouseInput.getX(),
+ mouseInput.getY());
+ }
+ else
+ {
+ Widget *const sourceWidget = getMouseEventSource(
+ mouseInput.getX(), mouseInput.getY());
+
+ distributeMouseEvent(sourceWidget,
+ MouseEvent::MOVED,
+ mouseInput.getButton(),
+ mouseInput.getX(),
+ mouseInput.getY());
+ }
+ }
+
+ void Gui::handleMouseWheelMovedDown(const MouseInput& mouseInput)
+ {
+ Widget* sourceWidget = getMouseEventSource(
+ mouseInput.getX(), mouseInput.getY());
+
+ if (mFocusHandler->getDraggedWidget())
+ sourceWidget = mFocusHandler->getDraggedWidget();
+
+ int sourceWidgetX, sourceWidgetY;
+ sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
+
+ distributeMouseEvent(sourceWidget,
+ MouseEvent::WHEEL_MOVED_DOWN,
+ mouseInput.getButton(),
+ mouseInput.getX(),
+ mouseInput.getY());
+ }
+
+ void Gui::handleMouseWheelMovedUp(const MouseInput& mouseInput)
+ {
+ Widget* sourceWidget = getMouseEventSource(
+ mouseInput.getX(), mouseInput.getY());
+
+ if (mFocusHandler->getDraggedWidget())
+ sourceWidget = mFocusHandler->getDraggedWidget();
+
+ int sourceWidgetX, sourceWidgetY;
+ sourceWidget->getAbsolutePosition(sourceWidgetX, sourceWidgetY);
+
+ distributeMouseEvent(sourceWidget,
+ MouseEvent::WHEEL_MOVED_UP,
+ mouseInput.getButton(),
+ mouseInput.getX(),
+ mouseInput.getY());
+ }
+
+ Widget* Gui::getWidgetAt(int x, int y)
+ {
+ // If the widget's parent has no child then we have found the widget..
+ Widget* parent = mTop;
+ Widget* child = mTop;
+
+ while (child)
+ {
+ Widget *const swap = child;
+ int parentX, parentY;
+ parent->getAbsolutePosition(parentX, parentY);
+ child = parent->getWidgetAt(x - parentX, y - parentY);
+ parent = swap;
+ }
+
+ return parent;
+ }
+
+ Widget* Gui::getMouseEventSource(int x, int y)
+ {
+ Widget *const widget = getWidgetAt(x, y);
+
+ // +++ possible nullpointer
+ if (mFocusHandler->getModalMouseInputFocused()
+ && !widget->isModalMouseInputFocused())
+ {
+ return mFocusHandler->getModalMouseInputFocused();
+ }
+
+ return widget;
+ }
+
+ Widget* Gui::getKeyEventSource()
+ {
+ Widget* widget = mFocusHandler->getFocused();
+
+ // +++ possible nullpointer
+ while (widget->_getInternalFocusHandler()
+ && widget->_getInternalFocusHandler()->getFocused())
+ {
+ widget = widget->_getInternalFocusHandler()->getFocused();
+ }
+
+ return widget;
+ }
+
+ void Gui::distributeMouseEvent(Widget* source,
+ int type,
+ int button,
+ int x,
+ int y,
+ bool force,
+ bool toSourceOnly)
+ {
+ Widget* parent = source;
+ Widget* widget = source;
+
+ if (mFocusHandler->getModalFocused()
+ && !widget->isModalFocused()
+ && !force)
+ {
+ return;
+ }
+
+ if (mFocusHandler->getModalMouseInputFocused()
+ && !widget->isModalMouseInputFocused()
+ && !force)
+ {
+ return;
+ }
+
+ MouseEvent mouseEvent(source,
+ mShiftPressed,
+ mControlPressed,
+ mAltPressed,
+ mMetaPressed,
+ type,
+ button,
+ x,
+ y,
+ mClickCount);
+
+ while (parent)
+ {
+ // If the widget has been removed due to input
+ // cancel the distribution.
+ if (!Widget::widgetExists(widget))
+ break;
+
+ parent = widget->getParent();
+
+ if (widget->isEnabled() || force)
+ {
+ int widgetX, widgetY;
+ widget->getAbsolutePosition(widgetX, widgetY);
+
+ mouseEvent.mX = x - widgetX;
+ mouseEvent.mY = y - widgetY;
+
+ std::list<MouseListener*> mouseListeners
+ = widget->_getMouseListeners();
+
+ // Send the event to all mouse listeners of the widget.
+ for (std::list<MouseListener*>::const_iterator
+ it = mouseListeners.begin();
+ it != mouseListeners.end();
+ ++it)
+ {
+ switch (mouseEvent.getType())
+ {
+ case MouseEvent::ENTERED:
+ (*it)->mouseEntered(mouseEvent);
+ break;
+ case MouseEvent::EXITED:
+ (*it)->mouseExited(mouseEvent);
+ break;
+ case MouseEvent::MOVED:
+ (*it)->mouseMoved(mouseEvent);
+ break;
+ case MouseEvent::PRESSED:
+ (*it)->mousePressed(mouseEvent);
+ break;
+ case MouseEvent::RELEASED:
+ (*it)->mouseReleased(mouseEvent);
+ break;
+ case MouseEvent::WHEEL_MOVED_UP:
+ (*it)->mouseWheelMovedUp(mouseEvent);
+ break;
+ case MouseEvent::WHEEL_MOVED_DOWN:
+ (*it)->mouseWheelMovedDown(mouseEvent);
+ break;
+ case MouseEvent::DRAGGED:
+ (*it)->mouseDragged(mouseEvent);
+ break;
+ case MouseEvent::CLICKED:
+ (*it)->mouseClicked(mouseEvent);
+ break;
+ default:
+ throw GCN_EXCEPTION("Unknown mouse event type.");
+ }
+ }
+
+ if (toSourceOnly)
+ break;
+ }
+
+ const Widget *const swap = widget;
+ widget = parent;
+ parent = swap->getParent();
+
+ // If a non modal focused widget has been reach
+ // and we have modal focus cancel the distribution.
+ if (mFocusHandler->getModalFocused()
+ && !widget->isModalFocused())
+ {
+ break;
+ }
+
+ // If a non modal mouse input focused widget has been reach
+ // and we have modal mouse input focus cancel the distribution.
+ if (mFocusHandler->getModalMouseInputFocused()
+ && !widget->isModalMouseInputFocused())
+ {
+ break;
+ }
+ }
+ }
+
+ void Gui::distributeKeyEvent(KeyEvent& keyEvent)
+ {
+ Widget* parent = keyEvent.getSource();
+ Widget* widget = keyEvent.getSource();
+
+ if (mFocusHandler->getModalFocused()
+ && !widget->isModalFocused())
+ {
+ return;
+ }
+
+ if (mFocusHandler->getModalMouseInputFocused()
+ && !widget->isModalMouseInputFocused())
+ {
+ return;
+ }
+
+ while (parent)
+ {
+ // If the widget has been removed due to input
+ // cancel the distribution.
+ if (!Widget::widgetExists(widget))
+ break;
+
+ parent = widget->getParent();
+
+ if (widget->isEnabled())
+ {
+ std::list<KeyListener*> keyListeners
+ = widget->_getKeyListeners();
+
+ // Send the event to all key listeners of the source widget.
+ for (std::list<KeyListener*>::const_iterator
+ it = keyListeners.begin();
+ it != keyListeners.end();
+ ++it)
+ {
+ switch (keyEvent.getType())
+ {
+ case KeyEvent::PRESSED:
+ (*it)->keyPressed(keyEvent);
+ break;
+ case KeyEvent::RELEASED:
+ (*it)->keyReleased(keyEvent);
+ break;
+ default:
+ throw GCN_EXCEPTION("Unknown key event type.");
+ }
+ }
+ }
+
+ const Widget *const swap = widget;
+ widget = parent;
+ parent = swap->getParent();
+
+ // If a non modal focused widget has been reach
+ // and we have modal focus cancel the distribution.
+ if (mFocusHandler->getModalFocused()
+ && !widget->isModalFocused())
+ {
+ break;
+ }
+ }
+ }
+
+ void Gui::distributeKeyEventToGlobalKeyListeners(KeyEvent& keyEvent)
+ {
+ for (KeyListenerListIterator it = mKeyListeners.begin();
+ it != mKeyListeners.end(); ++ it)
+ {
+ switch (keyEvent.getType())
+ {
+ case KeyEvent::PRESSED:
+ (*it)->keyPressed(keyEvent);
+ break;
+ case KeyEvent::RELEASED:
+ (*it)->keyReleased(keyEvent);
+ break;
+ default:
+ throw GCN_EXCEPTION("Unknown key event type.");
+ }
+
+ if (keyEvent.isConsumed())
+ break;
+ }
+ }
+
+ void Gui::handleModalMouseInputFocus()
+ {
+ BLOCK_START("Gui::handleModalMouseInputFocus")
+ // Check if modal mouse input focus has been gained by a widget.
+ if ((mFocusHandler->getLastWidgetWithModalMouseInputFocus()
+ != mFocusHandler->getModalMouseInputFocused())
+ && (!mFocusHandler->getLastWidgetWithModalMouseInputFocus()))
+ {
+ handleModalFocusGained();
+ mFocusHandler->setLastWidgetWithModalMouseInputFocus(
+ mFocusHandler->getModalMouseInputFocused());
+ }
+ // Check if modal mouse input focus has been released.
+ else if ((mFocusHandler->getLastWidgetWithModalMouseInputFocus()
+ != mFocusHandler->getModalMouseInputFocused())
+ && (mFocusHandler->getLastWidgetWithModalMouseInputFocus()))
+ {
+ handleModalFocusReleased();
+ mFocusHandler->setLastWidgetWithModalMouseInputFocus(nullptr);
+ }
+ BLOCK_END("Gui::handleModalMouseInputFocus")
+ }
+
+ void Gui::handleModalFocus()
+ {
+ BLOCK_START("Gui::handleModalFocus")
+ // Check if modal focus has been gained by a widget.
+ if ((mFocusHandler->getLastWidgetWithModalFocus()
+ != mFocusHandler->getModalFocused())
+ && (!mFocusHandler->getLastWidgetWithModalFocus()))
+ {
+ handleModalFocusGained();
+ mFocusHandler->setLastWidgetWithModalFocus(
+ mFocusHandler->getModalFocused());
+ }
+ // Check if modal focus has been released.
+ else if ((mFocusHandler->getLastWidgetWithModalFocus()
+ != mFocusHandler->getModalFocused())
+ && (mFocusHandler->getLastWidgetWithModalFocus()))
+ {
+ handleModalFocusReleased();
+ mFocusHandler->setLastWidgetWithModalFocus(nullptr);
+ }
+ BLOCK_END("Gui::handleModalFocus")
+ }
+
+ void Gui::handleModalFocusGained()
+ {
+ // Distribute an event to all widgets in the "widget with mouse" queue.
+ while (!mWidgetWithMouseQueue.empty())
+ {
+ Widget *const widget = mWidgetWithMouseQueue.front();
+
+ if (Widget::widgetExists(widget))
+ {
+ distributeMouseEvent(widget,
+ MouseEvent::EXITED,
+ mLastMousePressButton,
+ mLastMouseX,
+ mLastMouseY,
+ true,
+ true);
+ }
+
+ mWidgetWithMouseQueue.pop_front();
+ }
+
+ mFocusHandler->setLastWidgetWithModalMouseInputFocus(
+ mFocusHandler->getModalMouseInputFocused());
+ }
+
+ void Gui::handleModalFocusReleased()
+ {
+ // Check all widgets below the mouse to see if they are
+ // present in the "widget with mouse" queue. If a widget
+ // is not then it should be added and an entered event should
+ // be sent to it.
+ Widget* widget = getMouseEventSource(mLastMouseX, mLastMouseY);
+ Widget* parent = widget;
+
+ while (parent)
+ {
+ parent = widget->getParent();
+
+ // Check if the widget is present in the "widget with mouse" queue.
+ bool widgetIsPresentInQueue = false;
+ FOR_EACH (std::deque<Widget*>::const_iterator,
+ iter, mWidgetWithMouseQueue)
+ {
+ if (*iter == widget)
+ {
+ widgetIsPresentInQueue = true;
+ break;
+ }
+ }
+
+ // Widget is not present, send an entered event and add
+ // it to the "widget with mouse" queue.
+ if (!widgetIsPresentInQueue && Widget::widgetExists(widget))
+ {
+ distributeMouseEvent(widget,
+ MouseEvent::ENTERED,
+ mLastMousePressButton,
+ mLastMouseX,
+ mLastMouseY,
+ false,
+ true);
+ mWidgetWithMouseQueue.push_front(widget);
+ }
+
+ const Widget *const swap = widget;
+ widget = parent;
+ parent = swap->getParent();
+ }
+ }
+} // namespace gcn
diff --git a/src/gui/base/gui.hpp b/src/gui/base/gui.hpp
new file mode 100644
index 000000000..b1daba0fc
--- /dev/null
+++ b/src/gui/base/gui.hpp
@@ -0,0 +1,514 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_GUI_HPP
+#define GCN_GUI_HPP
+
+#include <list>
+#include <deque>
+
+#include "gui/base/keyevent.hpp"
+#include "gui/base/mouseevent.hpp"
+#include "gui/base/mouseinput.hpp"
+
+namespace gcn
+{
+ class FocusHandler;
+ class Graphics;
+ class Input;
+ class KeyListener;
+ class Widget;
+
+ // The following comment will appear in the doxygen main page.
+ /**
+ * @mainpage
+ * @section Introduction
+ * This documentation is mostly intended as a reference to the API.
+ * If you want to get started with Guichan, we suggest you check out
+ * the programs in the examples directory of the Guichan release.
+ * @n
+ * @n
+ * This documentation is, and will always be, work in progress.
+ * If you find any errors, typos or inconsistencies, or if you feel
+ * something needs to be explained in more detail - don't hesitate to
+ * tell us.
+ */
+
+ /**
+ * Contains a Guichan GUI. This is the core class of Guichan to which
+ * implementations of back ends are passed, to make Guichan work with
+ * a specific library, and to where the top widget (root widget of GUI)
+ * is added. If you want to be able to have more then one widget in your
+ * GUI, the top widget should be a container.
+ *
+ * A Gui object cannot work properly without passing back end
+ * implementations to it. A Gui object must have an implementation of a
+ * Graphics and an implementation of Input.
+ *
+ * NOTE: A complete GUI also must have the ability to load images.
+ * Images are loaded with the Image class, so to make Guichan
+ * able to load images an implementation of ImageLoader must be
+ * passed to Image.
+ *
+ * @see Graphics, Input, Image
+ */
+ class Gui
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ Gui();
+
+ A_DELETE_COPY(Gui)
+
+ /**
+ * Destructor.
+ */
+ virtual ~Gui();
+
+ /**
+ * Sets the top widget. The top widget is the root widget
+ * of the GUI. If you want a GUI to be able to contain more
+ * than one widget the top widget should be a container.
+ *
+ * @param top The top widget.
+ * @see Container
+ * @since 0.1.0
+ */
+ virtual void setTop(Widget* top);
+
+ /**
+ * Gets the top widget. The top widget is the root widget
+ * of the GUI.
+ *
+ * @return The top widget. NULL if no top widget has been set.
+ * @since 0.1.0
+ */
+ virtual Widget* getTop() const A_WARN_UNUSED;
+
+ /**
+ * Sets the graphics object to use for drawing.
+ *
+ * @param graphics The graphics object to use for drawing.
+ * @see getGraphics, AllegroGraphics, HGEGraphics,
+ * OpenLayerGraphics, OpenGLGraphics, SDLGraphics
+ * @since 0.1.0
+ */
+ virtual void setGraphics(Graphics* graphics);
+
+ /**
+ * Gets the graphics object used for drawing.
+ *
+ * @return The graphics object used for drawing. NULL if no
+ * graphics object has been set.
+ * @see setGraphics, AllegroGraphics, HGEGraphics,
+ * OpenLayerGraphics, OpenGLGraphics, SDLGraphics
+ * @since 0.1.0
+ */
+ virtual Graphics* getGraphics() const A_WARN_UNUSED;
+
+ /**
+ * Sets the input object to use for input handling.
+ *
+ * @param input The input object to use for input handling.
+ * @see getInput, AllegroInput, HGEInput, OpenLayerInput,
+ * SDLInput
+ * @since 0.1.0
+ */
+ virtual void setInput(Input* input);
+
+ /**
+ * Gets the input object being used for input handling.
+ *
+ * @return The input object used for handling input. NULL if no
+ * input object has been set.
+ * @see setInput, AllegroInput, HGEInput, OpenLayerInput,
+ * SDLInput
+ * @since 0.1.0
+ */
+ virtual Input* getInput() const A_WARN_UNUSED;
+
+ /**
+ * Performs logic of the GUI. By calling this function all logic
+ * functions down in the GUI heirarchy will be called. When logic
+ * is called for Gui, user input will be handled.
+ *
+ * @see Widget::logic
+ * @since 0.1.0
+ */
+ virtual void logic();
+
+ /**
+ * Draws the GUI. By calling this funcion all draw functions
+ * down in the GUI hierarchy will be called. When draw is called
+ * the used Graphics object will be initialised and drawing of
+ * the top widget will commence.
+ *
+ * @see Widget::draw
+ * @since 0.1.0
+ */
+ virtual void draw();
+
+ /**
+ * Focuses none of the widgets in the Gui.
+ *
+ * @since 0.1.0
+ */
+ virtual void focusNone();
+
+ /**
+ * Sets tabbing enabled, or not. Tabbing is the usage of
+ * changing focus by utilising the tab key.
+ *
+ * @param tabbing True if tabbing should be enabled, false
+ * otherwise.
+ * @see isTabbingEnabled
+ * @since 0.1.0
+ */
+ virtual void setTabbingEnabled(bool tabbing);
+
+ /**
+ * Checks if tabbing is enabled.
+ *
+ * @return True if tabbing is enabled, false otherwise.
+ * @see setTabbingEnabled
+ * @since 0.1.0
+ */
+ virtual bool isTabbingEnabled();
+
+ /**
+ * Adds a global key listener to the Gui. A global key listener
+ * will receive all key events generated from the GUI and global
+ * key listeners will receive the events before key listeners
+ * of widgets.
+ *
+ * @param keyListener The key listener to add.
+ * @see removeGlobalKeyListener
+ * @since 0.5.0
+ */
+ virtual void addGlobalKeyListener(KeyListener* keyListener);
+
+ /**
+ * Removes global key listener from the Gui.
+ *
+ * @param keyListener The key listener to remove.
+ * @throws Exception if the key listener hasn't been added.
+ * @see addGlobalKeyListener
+ * @since 0.5.0
+ */
+ virtual void removeGlobalKeyListener(KeyListener* keyListener);
+
+ protected:
+ /**
+ * Handles all mouse input.
+ *
+ * @since 0.6.0
+ */
+ virtual void handleMouseInput();
+
+ /**
+ * Handles key input.
+ *
+ * @since 0.6.0
+ */
+ virtual void handleKeyInput();
+
+ /**
+ * Handles mouse moved input.
+ *
+ * @param mouseInput The mouse input to handle.
+ * @since 0.6.0
+ */
+ virtual void handleMouseMoved(const MouseInput& mouseInput);
+
+ /**
+ *
+ * Handles mouse wheel moved down input.
+ *
+ * @param mouseInput The mouse input to handle.
+ * @since 0.6.0
+ */
+ virtual void handleMouseWheelMovedDown(const MouseInput& mouseInput);
+
+ /**
+ * Handles mouse wheel moved up input.
+ *
+ * @param mouseInput The mouse input to handle.
+ * @since 0.6.0
+ */
+ virtual void handleMouseWheelMovedUp(const MouseInput& mouseInput);
+
+ /**
+ * Handles modal focus. Modal focus needs to be checked at
+ * each logic iteration as it might be necessary to distribute
+ * mouse entered or mouse exited events.
+ *
+ * @since 0.8.0
+ */
+ virtual void handleModalFocus();
+
+ /**
+ * Handles modal mouse input focus. Modal mouse input focus needs
+ * to be checked at each logic iteration as it might be necessary to
+ * distribute mouse entered or mouse exited events.
+ *
+ * @since 0.8.0
+ */
+ virtual void handleModalMouseInputFocus();
+
+ /**
+ * Handles modal focus gained. If modal focus has been gained it might
+ * be necessary to distribute mouse entered or mouse exited events.
+ *
+ * @since 0.8.0
+ */
+ virtual void handleModalFocusGained();
+
+ /**
+ * Handles modal mouse input focus gained. If modal focus has been
+ * gained it might be necessary to distribute mouse entered or mouse
+ * exited events.
+ *
+ * @since 0.8.0
+ */
+ virtual void handleModalFocusReleased();
+
+ /**
+ * Distributes a mouse event.
+ *
+ * @param type The type of the event to distribute,
+ * @param button The button of the event (if any used) to distribute.
+ * @param x The x coordinate of the event.
+ * @param y The y coordinate of the event.
+ * @param fource indicates whether the distribution should be forced or not.
+ * A forced distribution distributes the event even if a widget
+ * is not enabled, not visible, another widget has modal
+ * focus or another widget has modal mouse input focus.
+ * Default value is false.
+ * @param toSourceOnly indicates whether the distribution should be to the
+ * source widget only or to it's parent's mouse listeners
+ * as well.
+ *
+ * @since 0.6.0
+ */
+ virtual void distributeMouseEvent(Widget* source,
+ int type,
+ int button,
+ int x,
+ int y,
+ bool force = false,
+ bool toSourceOnly = false);
+
+ /**
+ * Distributes a key event.
+ *
+ * @param keyEvent The key event to distribute.
+
+ * @since 0.6.0
+ */
+ virtual void distributeKeyEvent(KeyEvent& keyEvent);
+
+ /**
+ * Distributes a key event to the global key listeners.
+ *
+ * @param keyEvent The key event to distribute.
+ *
+ * @since 0.6.0
+ */
+ virtual void distributeKeyEventToGlobalKeyListeners(KeyEvent&
+ keyEvent);
+
+ /**
+ * Gets the widget at a certain position.
+ *
+ * @return The widget at a certain position.
+ * @since 0.6.0
+ */
+ virtual Widget* getWidgetAt(int x, int y) A_WARN_UNUSED;
+
+ /**
+ * Gets the source of the mouse event.
+ *
+ * @return The source widget of the mouse event.
+ * @since 0.6.0
+ */
+ virtual Widget* getMouseEventSource(int x, int y) A_WARN_UNUSED;
+
+ /**
+ * Gets the source of the key event.
+ *
+ * @return The source widget of the key event.
+ * @since 0.6.0
+ */
+ virtual Widget* getKeyEventSource() A_WARN_UNUSED;
+
+ /**
+ * Holds the top widget.
+ */
+ Widget* mTop;
+
+ /**
+ * Holds the graphics implementation used.
+ */
+ Graphics* mGraphics;
+
+ /**
+ * Holds the input implementation used.
+ */
+ Input* mInput;
+
+ /**
+ * Holds the focus handler for the Gui.
+ */
+ FocusHandler* mFocusHandler;
+
+ /**
+ * True if tabbing is enabled, false otherwise.
+ */
+ bool mTabbing;
+
+ /**
+ * Typedef.
+ */
+ typedef std::list<KeyListener*> KeyListenerList;
+
+ /**
+ * Typedef.
+ */
+ typedef KeyListenerList::iterator KeyListenerListIterator;
+
+ /**
+ * Holds the global key listeners of the Gui.
+ */
+ KeyListenerList mKeyListeners;
+
+ /**
+ * True if shift is pressed, false otherwise.
+ */
+ bool mShiftPressed;
+
+ /**
+ * True if meta is pressed, false otherwise.
+ */
+ bool mMetaPressed;
+
+ /**
+ * True if control is pressed, false otherwise.
+ */
+ bool mControlPressed;
+
+ /**
+ * True if alt is pressed, false otherwise.
+ */
+ bool mAltPressed;
+
+ /**
+ * Holds the last mouse button pressed.
+ */
+ unsigned int mLastMousePressButton;
+
+ /**
+ * Holds the last mouse press time stamp.
+ */
+ int mLastMousePressTimeStamp;
+
+ /**
+ * Holds the last mouse x coordinate.
+ */
+ int mLastMouseX;
+
+ /**
+ * Holds the last mouse y coordinate.
+ */
+ int mLastMouseY;
+
+ /**
+ * Holds the current click count. Used to keep track
+ * of clicks for a the last pressed button.
+ */
+ int mClickCount;
+
+ /**
+ * Holds the last button used when a drag of a widget
+ * was initiated. Used to be able to release a drag
+ * when the same button is released.
+ */
+ int mLastMouseDragButton;
+
+ /**
+ * Holds a stack with all the widgets with the mouse.
+ * Used to properly distribute mouse events.
+ */
+ std::deque<Widget*> mWidgetWithMouseQueue;
+ };
+} // namespace gcn
+
+#endif // end GCN_GUI_HPP
+
+/* yakslem - "Women, it's a constant struggle."
+ * finalman - "Yes, but sometimes they succeed with their guesses."
+ * yaklsem - "...eh...I was talking about love."
+ * finalman - "Oh...ok..."
+ * An awkward silence followed.
+ */
diff --git a/src/gui/base/image.cpp b/src/gui/base/image.cpp
new file mode 100644
index 000000000..01e30dc20
--- /dev/null
+++ b/src/gui/base/image.cpp
@@ -0,0 +1,83 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/image.hpp"
+
+#include "gui/base/exception.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Image::Image()
+ {
+ }
+
+ Image::~Image()
+ {
+ }
+}
diff --git a/src/gui/base/image.hpp b/src/gui/base/image.hpp
new file mode 100644
index 000000000..c39fe21ab
--- /dev/null
+++ b/src/gui/base/image.hpp
@@ -0,0 +1,162 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_IMAGE_HPP
+#define GCN_IMAGE_HPP
+
+#include <string>
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ class Color;
+
+ /**
+ * Holds an image. To be able to use this class you must first set an
+ * ImageLoader in Image by calling
+ * @code Image::setImageLoader(myImageLoader) @endcode
+ * The function is static. If this is not done, the constructor taking a
+ * filename will throw an exception. The ImageLoader you use must be
+ * compatible with the Graphics object you use.
+ *
+ * EXAMPLE: If you use SDLGraphics you should use SDLImageLoader.
+ * Otherwise your program might crash in a most bizarre way.
+ * @see AllegroImageLoader, HGEImageLoader, OpenLayerImageLoader,
+ * OpenGLAllegroImageLoader, OpenGLSDLImageLoader, SDLImageLoader
+ * @since 0.1.0
+ */
+ class Image
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ Image();
+
+ /**
+ * Destructor.
+ */
+ virtual ~Image();
+
+ /**
+ * Frees an image.
+ *
+ * @since 0.5.0
+ */
+ virtual void free() = 0;
+
+ /**
+ * Gets the width of the image.
+ *
+ * @return The width of the image.
+ *
+ * @since 0.1.0
+ */
+ virtual int getWidth() const A_WARN_UNUSED = 0;
+
+ /**
+ * Gets the height of the image.
+ *
+ * @return The height of the image.
+ *
+ * @since 0.1.0
+ */
+ virtual int getHeight() const A_WARN_UNUSED = 0;
+
+ /**
+ * Gets the color of a pixel at coordinate (x, y) in the image.
+ *
+ * IMPORTANT: Only guaranteed to work before the image has been
+ * converted to display format.
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @return The color of the pixel.
+ *
+ * @since 0.5.0
+ */
+ virtual Color getPixel(int x, int y) A_WARN_UNUSED = 0;
+
+ /**
+ * Puts a pixel with a certain color at coordinate (x, y).
+ *
+ * @param x The x coordinate.
+ * @param y The y coordinate.
+ * @param color The color of the pixel to put.
+ * @since 0.5.0
+ */
+ virtual void putPixel(int x, int y, const Color& color) = 0;
+
+ /**
+ * Converts the image, if possible, to display format.
+ *
+ * IMPORTANT: Only guaranteed to work before the image has been
+ * converted to display format.
+ * @since 0.5.0
+ */
+ virtual void convertToDisplayFormat() = 0;
+ };
+} // namespace gcn
+
+#endif // end GCN_IMAGE_HPP
diff --git a/src/gui/base/input.hpp b/src/gui/base/input.hpp
new file mode 100644
index 000000000..71a15ce85
--- /dev/null
+++ b/src/gui/base/input.hpp
@@ -0,0 +1,134 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_INPUT_HPP
+#define GCN_INPUT_HPP
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ class KeyInput;
+ class MouseInput;
+
+ /**
+ * Abstract class for providing functions for user input.
+ *
+ * Guichan contains implementations of Input for common
+ * libraries like the Allegro library, the HGE library,
+ * and the SDL library.
+ * To make Guichan usable with other libraries, an Input
+ * class must be implemented.
+ *
+ * @see AllegroInput, HGEInput, OpenLayerInput,
+ * SDLInput
+ */
+ class Input
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~Input(){ }
+
+ /**
+ * Checks if the key queue is empty, or not.
+ *
+ * @return True if the key queue is empty,
+ * false otherwise.
+ */
+ virtual bool isKeyQueueEmpty() A_WARN_UNUSED = 0;
+
+ /**
+ * Dequeues the key input queue.
+ *
+ * @return The first key input in the key input queue.
+ */
+ virtual KeyInput dequeueKeyInput() = 0;
+
+ /**
+ * Checks if the mouse queue is empyt, or not.
+ *
+ * @return True if the mouse queue is empty,
+ * false otherwise.
+ */
+ virtual bool isMouseQueueEmpty() A_WARN_UNUSED = 0;
+
+ /**
+ * Dequeues the mouse input queue.
+ *
+ * @return The first mouse input in the mouse input queue.
+ */
+ virtual MouseInput dequeueMouseInput() = 0;
+
+ /**
+ * Polls all exsisting input. Called when input should
+ * be polled. The function exists for compatibility reason
+ * where some libraries need to poll input at a certain
+ * logic rate.
+ */
+ virtual void _pollInput() = 0;
+ };
+} // namespace gcn
+
+#endif // end GCN_INPUT_HPP
diff --git a/src/gui/base/inputevent.cpp b/src/gui/base/inputevent.cpp
new file mode 100644
index 000000000..3251a102f
--- /dev/null
+++ b/src/gui/base/inputevent.cpp
@@ -0,0 +1,117 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/inputevent.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ InputEvent::InputEvent(Widget *const source,
+ const bool shiftPressed,
+ const bool controlPressed,
+ const bool altPressed,
+ const bool metaPressed)
+ :Event(source),
+ mShiftPressed(shiftPressed),
+ mControlPressed(controlPressed),
+ mAltPressed(altPressed),
+ mMetaPressed(metaPressed),
+ mIsConsumed(false)
+ {
+ }
+
+ bool InputEvent::isShiftPressed() const
+ {
+ return mShiftPressed;
+ }
+
+ bool InputEvent::isControlPressed() const
+ {
+ return mControlPressed;
+ }
+
+ bool InputEvent::isAltPressed() const
+ {
+ return mAltPressed;
+ }
+
+ bool InputEvent::isMetaPressed() const
+ {
+ return mMetaPressed;
+ }
+
+ void InputEvent::consume()
+ {
+ mIsConsumed = true;
+ }
+
+ bool InputEvent::isConsumed() const
+ {
+ return mIsConsumed;
+ }
+} // namespace gcn
diff --git a/src/gui/base/inputevent.hpp b/src/gui/base/inputevent.hpp
new file mode 100644
index 000000000..166edf038
--- /dev/null
+++ b/src/gui/base/inputevent.hpp
@@ -0,0 +1,177 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_INPUTEVENT_HPP
+#define GCN_INPUTEVENT_HPP
+
+#include "gui/base/event.hpp"
+
+namespace gcn
+{
+ /**
+ * Base class for all events concerning input.
+ *
+ * @author Olof Naessén
+ * @since 0.6.0
+ */
+ class InputEvent: public Event
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param source The source widget of the event.
+ * @param isShiftPressed True if shift is pressed, false otherwise.
+ * @param isControlPressed True if control is pressed, false otherwise.
+ * @param isAltPressed True if alt is pressed, false otherwise.
+ * @param isMetaPressed True if meta is pressed, false otherwise.
+ */
+ InputEvent(Widget *const source,
+ const bool shiftPressed,
+ const bool controlPressed,
+ const bool altPressed,
+ const bool metaPressed);
+
+ /**
+ * Checks if shift is pressed.
+ *
+ * @return True if shift was pressed at the same time as the key,
+ * false otherwise.
+ */
+ bool isShiftPressed() const A_WARN_UNUSED;
+
+ /**
+ * Checks if control is pressed.
+ *
+ * @return True if control was pressed at the same time as the key,
+ * false otherwise.
+ */
+ bool isControlPressed() const A_WARN_UNUSED;
+
+ /**
+ * Checks if alt is pressed.
+ *
+ * @return True if alt was pressed at the same time as the key,
+ * false otherwise.
+ */
+ bool isAltPressed() const A_WARN_UNUSED;
+
+ /**
+ * Checks whether meta is pressed.
+ *
+ * @return True if meta was pressed at the same time as the key,
+ * false otherwise.
+ */
+ bool isMetaPressed() const A_WARN_UNUSED;
+
+ /**
+ * Marks the event as consumed. Input event listeners may discard
+ * consumed input or act on consumed input. An example of a widget
+ * that discards consumed input is the ScrollArea widget that
+ * discards consumed mouse wheel events so the ScrollArea will not
+ * scroll if for instance a Slider's value inside the ScrollArea was
+ * changed with the mouse wheel.
+ *
+ * @see isConsumed
+ */
+ void consume();
+
+ /**
+ * Checks if the input event is consumed.
+ *
+ * @return True if the input event is consumed,
+ * false otherwise.
+ * @see consume
+ */
+ bool isConsumed() const A_WARN_UNUSED;
+
+ protected:
+ /**
+ * True if shift is pressed, false otherwise.
+ */
+ bool mShiftPressed;
+
+ /**
+ * True if control is pressed, false otherwise.
+ */
+ bool mControlPressed;
+
+ /**
+ * True if alt is pressed, false otherwise.
+ */
+ bool mAltPressed;
+
+ /**
+ * True if meta is pressed, false otherwise.
+ */
+ bool mMetaPressed;
+
+ /**
+ * True if the input event is consumed,
+ * false otherwise.
+ */
+ bool mIsConsumed;
+ };
+} // namespace gcn
+
+#endif // end GCN_INPUTEVENT_HPP
diff --git a/src/gui/base/key.cpp b/src/gui/base/key.cpp
new file mode 100644
index 000000000..8cf21bdfe
--- /dev/null
+++ b/src/gui/base/key.cpp
@@ -0,0 +1,113 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/key.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Key::Key(const int value) :
+ mValue(value)
+ {
+ }
+
+ bool Key::isCharacter() const
+ {
+ return (mValue >= 32 && mValue <= 126)
+ || (mValue >= 162 && mValue <= 255)
+ || (mValue == 9);
+ }
+
+ bool Key::isNumber() const
+ {
+ return mValue >= 48 && mValue <= 57;
+ }
+
+ bool Key::isLetter() const
+ {
+ return (((mValue >= 65 && mValue <= 90)
+ || (mValue >= 97 && mValue <= 122)
+ || (mValue >= 192 && mValue <= 255))
+ && (mValue != 215) && (mValue != 247));
+ }
+
+ int Key::getValue() const
+ {
+ return mValue;
+ }
+
+ bool Key::operator==(const Key& key) const
+ {
+ return mValue == key.mValue;
+ }
+
+ bool Key::operator!=(const Key& key) const
+ {
+ return (mValue != key.mValue);
+ }
+} // namespace gcn
diff --git a/src/gui/base/key.hpp b/src/gui/base/key.hpp
new file mode 100644
index 000000000..46b36a179
--- /dev/null
+++ b/src/gui/base/key.hpp
@@ -0,0 +1,201 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_KEY_HPP
+#define GCN_KEY_HPP
+
+#include "localconsts.h"
+
+// windows.h defines DELETE which breaks this file as we have a constant named
+// DELETE, hence we undefine DELETE if it is defined and hope people don't use
+// that windows define with Guichan.
+#if defined (_WIN32) && defined(DELETE)
+#undef DELETE
+#endif
+
+namespace gcn
+{
+ /**
+ * Represents a key or a character.
+ */
+ class Key final
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param value The ascii or enum value for the key.
+ */
+ explicit Key(const int value = 0);
+
+ /**
+ * Checks if a key is a character.
+ *
+ * @return True if the key is a letter, number or whitespace,
+ * false otherwise.
+ */
+ bool isCharacter() const A_WARN_UNUSED;
+
+ /**
+ * Checks if a key is a number.
+ *
+ * @return True if the key is a number (0-9),
+ * false otherwise.
+ */
+ bool isNumber() const A_WARN_UNUSED;
+
+ /**
+ * Checks if a key is a letter.
+ *
+ * @return True if the key is a letter (a-z,A-Z),
+ * false otherwise.
+ */
+ bool isLetter() const A_WARN_UNUSED;
+
+ /**
+ * Gets the value of the key. If an ascii value exists it
+ * will be returned. Otherwise an enum value will be returned.
+ *
+ * @return the value of the key.
+ */
+ int getValue() const A_WARN_UNUSED;
+
+ /**
+ * Compares two keys.
+ *
+ * @param key The key to compare this key with.
+ * @return True if the keys are equal, false otherwise.
+ */
+ bool operator==(const Key& key) const;
+
+ /**
+ * Compares two keys.
+ *
+ * @param key The key to compare this key with.
+ * @return True if the keys are not equal, false otherwise.
+ */
+ bool operator!=(const Key& key) const;
+
+ /**
+ * An enum with key values.
+ */
+ enum
+ {
+ SPACE = ' ',
+ TAB = '\t',
+ ENTER = '\n',
+ LEFT_ALT = 1000,
+ RIGHT_ALT,
+ LEFT_SHIFT,
+ RIGHT_SHIFT,
+ LEFT_CONTROL,
+ RIGHT_CONTROL,
+ LEFT_META,
+ RIGHT_META,
+ LEFT_SUPER,
+ RIGHT_SUPER,
+ INSERT,
+ HOME,
+ PAGE_UP,
+ DELETE,
+ END,
+ PAGE_DOWN,
+ ESCAPE,
+ CAPS_LOCK,
+ BACKSPACE,
+ F1,
+ F2,
+ F3,
+ F4,
+ F5,
+ F6,
+ F7,
+ F8,
+ F9,
+ F10,
+ F11,
+ F12,
+ F13,
+ F14,
+ F15,
+ PRINT_SCREEN,
+ SCROLL_LOCK,
+ PAUSE,
+ NUM_LOCK,
+ ALT_GR,
+ LEFT,
+ RIGHT,
+ UP,
+ DOWN
+ };
+
+ protected:
+ /**
+ * Holds the value of the key. It may be an ascii value
+ * or an enum value.
+ */
+ int mValue;
+ };
+} // namespace gcn
+
+#endif // end GCN_KEY_HPP
diff --git a/src/gui/base/keyevent.cpp b/src/gui/base/keyevent.cpp
new file mode 100644
index 000000000..35c4f06a5
--- /dev/null
+++ b/src/gui/base/keyevent.cpp
@@ -0,0 +1,111 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/keyevent.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ KeyEvent::KeyEvent(Widget *const source,
+ const bool shiftPressed,
+ const bool controlPressed,
+ const bool altPressed,
+ const bool metaPressed,
+ const unsigned int type,
+ const bool numericPad,
+ const Key& key) :
+ InputEvent(source,
+ shiftPressed,
+ controlPressed,
+ altPressed,
+ metaPressed),
+ mType(type),
+ mIsNumericPad(numericPad),
+ mKey(key)
+ {
+ }
+
+ KeyEvent::~KeyEvent()
+ {
+ }
+
+ unsigned int KeyEvent::getType() const
+ {
+ return mType;
+ }
+
+ bool KeyEvent::isNumericPad() const
+ {
+ return mIsNumericPad;
+ }
+
+ const Key& KeyEvent::getKey() const
+ {
+ return mKey;
+ }
+} // namespace gcn
diff --git a/src/gui/base/keyevent.hpp b/src/gui/base/keyevent.hpp
new file mode 100644
index 000000000..4f2fa05a3
--- /dev/null
+++ b/src/gui/base/keyevent.hpp
@@ -0,0 +1,157 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_KEYEVENT_HPP
+#define GCN_KEYEVENT_HPP
+
+#include "gui/base/inputevent.hpp"
+#include "gui/base/key.hpp"
+
+namespace gcn
+{
+ class Widget;
+
+ /**
+ * Represents a key event.
+ */
+ class KeyEvent: public InputEvent
+ {
+ public:
+ /**
+ * Key event types.
+ */
+ enum
+ {
+ PRESSED = 0,
+ RELEASED
+ };
+
+ /**
+ * Constructor.
+ *
+ * @param source The source widget of the event.
+ * @param shiftPressed True if shift is pressed, false otherwise.
+ * @param controlPressed True if control is pressed, false otherwise.
+ * @param altPressed True if alt is pressed, false otherwise.
+ * @param metaPressed True if meta is pressed, false otherwise.
+ * @param type The type of the event. A value from KeyEventType.
+ * @param numericPad True if the event occured on the numeric pad,
+ * false otherwise.
+ * @param key The key of the event.
+ */
+ KeyEvent(Widget *const source,
+ const bool shiftPressed,
+ const bool controlPressed,
+ const bool altPressed,
+ const bool metaPressed,
+ const unsigned int type,
+ const bool numericPad,
+ const Key& key);
+
+ /**
+ * Destructor.
+ */
+ virtual ~KeyEvent();
+
+ /**
+ * Gets the type of the event.
+ *
+ * @return The type of the event.
+ */
+ unsigned int getType() const A_WARN_UNUSED;
+
+ /**
+ * Checks if the key event occured on the numeric pad.
+ *
+ * @return True if key event occured on the numeric pad,
+ * false otherwise.
+ *
+ */
+ bool isNumericPad() const A_WARN_UNUSED;
+
+ /**
+ * Gets the key of the event.
+ *
+ * @return The key of the event.
+ */
+ const Key& getKey() const A_WARN_UNUSED;
+
+ protected:
+ /**
+ * Holds the type of the key event.
+ */
+ unsigned int mType;
+
+ /**
+ * True if the numeric pad was used, false otherwise.
+ */
+ bool mIsNumericPad;
+
+ /**
+ * Holds the key of the key event.
+ */
+ Key mKey;
+ };
+} // namespace gcn
+
+#endif // end GCN_KEYEVENT_HPP
diff --git a/src/gui/base/keyinput.cpp b/src/gui/base/keyinput.cpp
new file mode 100644
index 000000000..8b7ff3c8a
--- /dev/null
+++ b/src/gui/base/keyinput.cpp
@@ -0,0 +1,154 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/keyinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ KeyInput::KeyInput(const Key& key, unsigned int type) :
+ mKey(key),
+ mType(type),
+ mShiftPressed(false),
+ mControlPressed(false),
+ mAltPressed(false),
+ mMetaPressed(false),
+ mNumericPad(false)
+ {
+ }
+
+ void KeyInput::setType(unsigned int type)
+ {
+ mType = type;
+ }
+
+ int KeyInput::getType() const
+ {
+ return mType;
+ }
+
+ void KeyInput::setKey(const Key& key)
+ {
+ mKey = key;
+ }
+
+ const Key& KeyInput::getKey() const
+ {
+ return mKey;
+ }
+
+ bool KeyInput::isShiftPressed() const
+ {
+ return mShiftPressed;
+ }
+
+ void KeyInput::setShiftPressed(bool pressed)
+ {
+ mShiftPressed = pressed;
+ }
+
+ bool KeyInput::isControlPressed() const
+ {
+ return mControlPressed;
+ }
+
+ void KeyInput::setControlPressed(bool pressed)
+ {
+ mControlPressed = pressed;
+ }
+
+ bool KeyInput::isAltPressed() const
+ {
+ return mAltPressed;
+ }
+
+ void KeyInput::setAltPressed(bool pressed)
+ {
+ mAltPressed = pressed;
+ }
+
+ bool KeyInput::isMetaPressed() const
+ {
+ return mMetaPressed;
+ }
+
+ void KeyInput::setMetaPressed(bool pressed)
+ {
+ mMetaPressed = pressed;
+ }
+
+ bool KeyInput::isNumericPad() const
+ {
+ return mNumericPad;
+ }
+
+ void KeyInput::setNumericPad(bool numpad)
+ {
+ mNumericPad = numpad;
+ }
+} // namespace gcn
diff --git a/src/gui/base/keyinput.hpp b/src/gui/base/keyinput.hpp
new file mode 100644
index 000000000..422d9046c
--- /dev/null
+++ b/src/gui/base/keyinput.hpp
@@ -0,0 +1,289 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_KEYINPUT_HPP
+#define GCN_KEYINPUT_HPP
+
+#include "gui/base/key.hpp"
+
+namespace gcn
+{
+ /**
+ * Internal class that represents key input. Generally you won't have to
+ * bother using this class unless you implement an Input class for
+ * a back end.
+ *
+ * @since 0.1.0
+ */
+ class KeyInput
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ KeyInput() :
+ mKey(0),
+ mType(0),
+ mShiftPressed(false),
+ mControlPressed(false),
+ mAltPressed(false),
+ mMetaPressed(false),
+ mNumericPad(false)
+ { }
+
+ /**
+ * Constructor.
+ *
+ * @param key The key of the key input.
+ * @param type The type of key input.
+ */
+ KeyInput(const Key& key, unsigned int type);
+
+ /**
+ * Sets the type of the key input.
+ *
+ * @param type The type of key input.
+ * @see getType
+ */
+ void setType(unsigned int type);
+
+ /**
+ * Gets the type of the key input.
+ *
+ * @return the input type.
+ * @see setType
+ */
+ int getType() const A_WARN_UNUSED;
+
+ /**
+ * Sets the key of the key input.
+ *
+ * @param key The key of the key input.
+ * @see getKey
+ */
+ void setKey(const Key& key);
+
+ /**
+ * Gets the key of the key input.
+ *
+ * @return The key of the key input.
+ * @see setKey
+ */
+ const Key& getKey() const A_WARN_UNUSED;
+
+ /**
+ * Checks if shift is pressed.
+ *
+ * @return True if shift was pressed at the same
+ * time as the key, false otherwise.
+ * @see setShiftPressed
+ * @since 0.6.0
+ */
+ bool isShiftPressed() const A_WARN_UNUSED;
+
+ /**
+ * Sets shift to be pressed at the same time as the key,
+ * or not.
+ *
+ * @param pressed True if shift is pressed, false otherwise.
+ * @see isShiftPressed
+ * @since 0.6.0
+ */
+ void setShiftPressed(bool pressed);
+
+ /**
+ * Checks if control is pressed.
+ *
+ * @return True if control was pressed at the same
+ * time as the key, false otherwise.
+ * @see setControlPressed
+ * @since 0.6.0
+ */
+ bool isControlPressed() const A_WARN_UNUSED;
+
+ /**
+ * Sets control to be pressed at the same time as the key,
+ * or not.
+ *
+ * @param pressed True if control is pressed, false otherwise.
+ * @see isControlPressed
+ * @since 0.6.0
+ */
+ void setControlPressed(bool pressed);
+
+ /**
+ * Checks if alt is pressed.
+ *
+ * @return True if alt was pressed at the same
+ * time as the key, false otherwise.
+ * @see setAltPressed
+ * @since 0.6.0
+ */
+ bool isAltPressed() const;
+
+ /**
+ * Sets the alt to be pressed at the same time as the key,
+ * or not.
+ *
+ * @param pressed True if alt is pressed at the same
+ * time as the key, , false otherwise.
+ * @see isAltPressed
+ * @since 0.6.0
+ */
+ void setAltPressed(bool pressed);
+
+ /**
+ * Checks if meta is pressed.
+ *
+ * @return True if meta was pressed at the same
+ * time as the key, false otherwise.
+ * @see setMetaPressed
+ * @since 0.6.0
+ */
+ bool isMetaPressed() const A_WARN_UNUSED;
+
+ /**
+ * Sets meta to be pressed at the same time as the key,
+ * or not.
+ *
+ * @param pressed True if meta is pressed at the same
+ * time as the key, false otherwise.
+ * @see isMetaPressed
+ * @since 0.6.0
+ */
+ void setMetaPressed(bool pressed);
+
+ /**
+ * Checks if the key was pressed at the numeric pad.
+ *
+ * @return True if key pressed at the numeric pad,
+ * false otherwise.
+ * @setNumericPad
+ * @since 0.6.0
+ */
+ bool isNumericPad() const A_WARN_UNUSED;
+
+ /**
+ * Sets the key to be pressed at the numeric pad.
+ *
+ * @param numpad True if the key was pressed at the numeric
+ * pad, false otherwise.
+ * @see isNumericPad
+ * @since 0.6.0
+ */
+ void setNumericPad(bool numpad);
+
+ /**
+ * Key input types. This enum corresponds to the enum with event
+ * types on KeyEvent for easy mapping.
+ */
+ enum
+ {
+ PRESSED = 0,
+ RELEASED
+ };
+
+ protected:
+ /**
+ * Holds the key of the key input.
+ */
+ Key mKey;
+
+ /**
+ * Holds the type of the key input.
+ */
+ unsigned int mType;
+
+ /**
+ * True if shift was pressed at the same time as the key,
+ * false otherwise.
+ */
+ bool mShiftPressed;
+
+ /**
+ * True if control was pressed at the same time as the key,
+ * false otherwise.
+ */
+ bool mControlPressed;
+
+ /**
+ * True if alt was pressed at the same time as the key,
+ * false otherwise.
+ */
+ bool mAltPressed;
+
+ /**
+ * True if meta was pressed at the same time as the key,
+ * false otherwise.
+ */
+ bool mMetaPressed;
+
+ /**
+ * True if the numeric pad was used when the key was pressed,
+ * false otherwise.
+ */
+ bool mNumericPad;
+ };
+} // namespace gcn
+
+#endif // end GCN_KEYINPUT_HPP
diff --git a/src/gui/base/keylistener.hpp b/src/gui/base/keylistener.hpp
new file mode 100644
index 000000000..088a937a6
--- /dev/null
+++ b/src/gui/base/keylistener.hpp
@@ -0,0 +1,119 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_KEYLISTENER_HPP
+#define GCN_KEYLISTENER_HPP
+
+#include "gui/base/keyevent.hpp"
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ class Key;
+
+ /**
+ * Interface for listening for key events from widgets.
+ *
+ * @see Widget::addKeyListener, Widget::removeKeyListener
+ */
+ class KeyListener
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~KeyListener()
+ { }
+
+ /**
+ * Called if a key is pressed when the widget has keyboard focus.
+ * If a key is held down the widget will generate multiple key
+ * presses.
+ *
+ * @param keyEvent Discribes the event.
+ */
+ virtual void keyPressed(KeyEvent& keyEvent A_UNUSED)
+ { }
+
+ /**
+ * Called if a key is released when the widget has keyboard focus.
+ *
+ * @param keyEvent Discribes the event.
+ */
+ virtual void keyReleased(KeyEvent& keyEvent A_UNUSED)
+ { }
+
+ protected:
+ /**
+ * Constructor.
+ *
+ * You should not be able to make an instance of KeyListener,
+ * therefore its constructor is protected.
+ */
+ KeyListener()
+ { }
+ };
+} // namespace gcn
+
+#endif // end GCN_KEYLISTENER_HPP
diff --git a/src/gui/base/listmodel.hpp b/src/gui/base/listmodel.hpp
new file mode 100644
index 000000000..4b98f46fe
--- /dev/null
+++ b/src/gui/base/listmodel.hpp
@@ -0,0 +1,106 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_LISTMODEL_HPP
+#define GCN_LISTMODEL_HPP
+
+#include <string>
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ /**
+ * An interface for a model that represents a list. It is
+ * used in certain widgets, like the ListBox, to handle a
+ * lists with string elements. If you want to use widgets
+ * like ListBox, make a derived class from this class that
+ * represents your list.
+ */
+ class ListModel
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~ListModel()
+ { }
+
+ /**
+ * Gets the number of elements in the list.
+ *
+ * @return The number of elements in the list
+ */
+ virtual int getNumberOfElements() A_WARN_UNUSED = 0;
+
+ /**
+ * Gets an element at a certain index in the list.
+ *
+ * @param i An index in the list.
+ * @return An element as a string at the a certain index.
+ */
+ virtual std::string getElementAt(int i) A_WARN_UNUSED = 0;
+ };
+} // namespace gcn
+
+#endif // end GCN_LISTMODEL_HPP
diff --git a/src/gui/base/mouseevent.cpp b/src/gui/base/mouseevent.cpp
new file mode 100644
index 000000000..653974a83
--- /dev/null
+++ b/src/gui/base/mouseevent.cpp
@@ -0,0 +1,121 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/mouseevent.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ MouseEvent::MouseEvent(Widget *const source,
+ const bool shiftPressed,
+ const bool controlPressed,
+ const bool altPressed,
+ const bool metaPressed,
+ const unsigned int type,
+ const unsigned int button,
+ const int x,
+ const int y,
+ const int clickCount) :
+ InputEvent(source,
+ shiftPressed,
+ controlPressed,
+ altPressed,
+ metaPressed),
+ mType(type),
+ mButton(button),
+ mX(x),
+ mY(y),
+ mClickCount(clickCount)
+ {
+ }
+
+ unsigned int MouseEvent::getButton() const
+ {
+ return mButton;
+ }
+
+ int MouseEvent::getX() const
+ {
+ return mX;
+ }
+
+ int MouseEvent::getY() const
+ {
+ return mY;
+ }
+
+ int MouseEvent::getClickCount() const
+ {
+ return mClickCount;
+ }
+
+ unsigned int MouseEvent::getType() const
+ {
+ return mType;
+ }
+} // namespace gcn
diff --git a/src/gui/base/mouseevent.hpp b/src/gui/base/mouseevent.hpp
new file mode 100644
index 000000000..93c1fc0a7
--- /dev/null
+++ b/src/gui/base/mouseevent.hpp
@@ -0,0 +1,217 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_MOUSEEVENT_HPP
+#define GCN_MOUSEEVENT_HPP
+
+#include "gui/base/inputevent.hpp"
+
+namespace gcn
+{
+ class Gui;
+ class Widget;
+
+ /**
+ * Represents a mouse event.
+ *
+ * @author Olof Naessén
+ * @since 0.6.0
+ */
+ class MouseEvent: public InputEvent
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param source The source widget of the mouse event.
+ * @param shiftPressed True if shift is pressed, false otherwise.
+ * @param controlPressed True if control is pressed, false otherwise.
+ * @param altPressed True if alt is pressed, false otherwise.
+ * @param metaPressed True if meta is pressed, false otherwise.
+ * @param type The type of the mouse event.
+ * @param button The button of the mouse event.
+ * @param x The x coordinate of the event relative to the source widget.
+ * @param y The y coordinate of the event relative the source widget.
+ * @param clickCount The number of clicks generated with the same button.
+ * It's set to zero if another button is used.
+ */
+ MouseEvent(Widget *const source,
+ const bool shiftPressed,
+ const bool controlPressed,
+ const bool altPressed,
+ const bool metaPressed,
+ const unsigned int type,
+ const unsigned int button,
+ const int x,
+ const int y,
+ const int clickCount);
+
+ /**
+ * Gets the button of the mouse event.
+ *
+ * @return The button of the mouse event.
+ */
+ unsigned int getButton() const A_WARN_UNUSED;
+
+ /**
+ * Gets the x coordinate of the mouse event.
+ * The coordinate relative to widget the mouse listener
+ * receiving the events have registered to.
+ *
+ * @return The x coordinate of the mouse event.
+ * @see Widget::addMouseListener, Widget::removeMouseListener
+ */
+ int getX() const A_WARN_UNUSED;
+
+ /**
+ * Gets the y coordinate of the mouse event.
+ * The coordinate relative to widget the mouse listener
+ * receiving the events have registered to.
+ *
+ * @return The y coordinate of the mouse event.
+ * @see Widget::addMouseListener, Widget::removeMouseListener
+ */
+ int getY() const A_WARN_UNUSED;
+
+ /**
+ * Gets the number of clicks generated with the same button.
+ * It's set to zero if another button is used.
+ *
+ * @return The number of clicks generated with the same button.
+ */
+ int getClickCount() const A_WARN_UNUSED;
+
+ /**
+ * Gets the type of the event.
+ *
+ * @return The type of the event.
+ */
+ unsigned int getType() const A_WARN_UNUSED;
+
+ /**
+ * Mouse event types.
+ */
+ enum
+ {
+ MOVED = 0,
+ PRESSED,
+ RELEASED,
+ WHEEL_MOVED_DOWN,
+ WHEEL_MOVED_UP,
+ CLICKED,
+ ENTERED,
+ EXITED,
+ DRAGGED
+ };
+
+ /**
+ * Mouse button types.
+ */
+ enum
+ {
+ EMPTY = 0,
+ LEFT,
+ RIGHT,
+ MIDDLE
+ };
+
+ protected:
+ /**
+ * Holds the type of the mouse event.
+ */
+ unsigned int mType;
+
+ /**
+ * Holds the button of the mouse event.
+ */
+ unsigned int mButton;
+
+ /**
+ * Holds the x-coordinate of the mouse event.
+ */
+ int mX;
+
+ /**
+ * Holds the y-coordinate of the mouse event.
+ */
+ int mY;
+
+ /**
+ * The number of clicks generated with the same button.
+ * It's set to zero if another button is used.
+ */
+ int mClickCount;
+
+ /**
+ * Gui is a friend of this class in order to be able to manipulate
+ * the protected member variables of this class and at the same time
+ * keep the MouseEvent class as const as possible. Gui needs to
+ * update the x och y coordinates for the coordinates to be relative
+ * to widget the mouse listener receiving the events have registered
+ * to.
+ */
+ friend class Gui;
+ };
+} // namespace gcn
+
+#endif // GCN_MOUSEEVENT_HPP
diff --git a/src/gui/base/mouseinput.cpp b/src/gui/base/mouseinput.cpp
new file mode 100644
index 000000000..bc5d6c8e0
--- /dev/null
+++ b/src/gui/base/mouseinput.cpp
@@ -0,0 +1,136 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ MouseInput::MouseInput(const unsigned int button,
+ const unsigned int type,
+ const int x,
+ const int y,
+ const int timeStamp) :
+ mType(type),
+ mButton(button),
+ mTimeStamp(timeStamp),
+ mX(x),
+ mY(y)
+ {
+ }
+
+ void MouseInput::setType(unsigned int type)
+ {
+ mType = type;
+ }
+
+ unsigned int MouseInput::getType() const
+ {
+ return mType;
+ }
+
+ void MouseInput::setButton(unsigned int button)
+ {
+ mButton = button;
+ }
+
+ unsigned int MouseInput::getButton() const
+ {
+ return mButton;
+ }
+
+ int MouseInput::getTimeStamp() const
+ {
+ return mTimeStamp;
+ }
+
+ void MouseInput::setTimeStamp(int timeStamp)
+ {
+ mTimeStamp = timeStamp;
+ }
+
+ void MouseInput::setX(int x)
+ {
+ mX = x;
+ }
+
+ int MouseInput::getX() const
+ {
+ return mX;
+ }
+
+ void MouseInput::setY(int y)
+ {
+ mY = y;
+ }
+
+ int MouseInput::getY() const
+ {
+ return mY;
+ }
+} // namespace gcn
diff --git a/src/gui/base/mouseinput.hpp b/src/gui/base/mouseinput.hpp
new file mode 100644
index 000000000..018205740
--- /dev/null
+++ b/src/gui/base/mouseinput.hpp
@@ -0,0 +1,260 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_MOUSEINPUT_HPP
+#define GCN_MOUSEINPUT_HPP
+
+#include "localconsts.h"
+
+namespace gcn
+{
+
+ /**
+ * Internal class that represents mouse input. Generally you won't have to
+ * bother using this class unless you implement an Input class for
+ * a back end.
+ *
+ * @author Olof Naessén
+ * @author Per Larsson
+ * @since 0.1.0
+ */
+ class MouseInput
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ MouseInput() :
+ mType(0),
+ mButton(0),
+ mTimeStamp(0),
+ mX(0),
+ mY(0)
+ { }
+
+ /**
+ * Constructor.
+ *
+ * @param button The button pressed.
+ * @param type The type of mouse input.
+ * @param x The mouse x coordinate.
+ * @param y The mouse y coordinate.
+ * @param timeStamp The timestamp of the mouse input. Used to
+ * check for double clicks.
+ */
+ MouseInput(const unsigned int button,
+ const unsigned int type,
+ const int x,
+ const int y,
+ const int timeStamp);
+
+ /**
+ * Sets the type of the mouse input.
+ *
+ * @param type The type of the mouse input. Should be a value from the
+ * mouse event type enum
+ * @see getType
+ * @since 0.1.0
+ */
+ void setType(unsigned int type);
+
+ /**
+ * Gets the type of the mouse input.
+ *
+ * @return The type of the mouse input. A value from the mouse event
+ * type enum.
+ * @see setType
+ * @since 0.1.0
+ */
+ unsigned int getType() const A_WARN_UNUSED;
+
+ /**
+ * Sets the button pressed.
+ *
+ * @param button The button pressed. Should be one of the values
+ * in the mouse event button enum.
+ * @see getButton.
+ * @since 0.1.0
+ */
+ void setButton(unsigned int button);
+
+ /**
+ * Gets the button pressed.
+ *
+ * @return The button pressed. A value from the mouse event
+ * button enum.
+ * @see setButton
+ * @since 0.1.0
+ */
+ unsigned int getButton() const A_WARN_UNUSED;
+
+ /**
+ * Sets the timestamp for the mouse input.
+ * Used to check for double clicks.
+ *
+ * @param timeStamp The timestamp of the mouse input.
+ * @see getTimeStamp
+ * @since 0.1.0
+ */
+ void setTimeStamp(int timeStamp);
+
+ /**
+ * Gets the time stamp of the input.
+ * Used to check for double clicks.
+ *
+ * @return The time stamp of the mouse input.
+ * @see setTimeStamp
+ * @since 0.1.0
+ */
+ int getTimeStamp() const A_WARN_UNUSED;
+
+ /**
+ * Sets the x coordinate of the mouse input.
+ *
+ * @param x The x coordinate of the mouse input.
+ * @see getX
+ * @since 0.6.0
+ */
+ void setX(int x);
+
+ /**
+ * Gets the x coordinate of the mouse input.
+ *
+ * @return The x coordinate of the mouse input.
+ * @see setX
+ * @since 0.6.0
+ */
+ int getX() const A_WARN_UNUSED;
+
+ /**
+ * Sets the y coordinate of the mouse input.
+ *
+ * @param y The y coordinate of the mouse input.
+ * @see getY
+ * @since 0.6.0
+ */
+ void setY(int y);
+
+ /**
+ * Gets the y coordinate of the mouse input.
+ *
+ * @return The y coordinate of the mouse input.
+ * @see setY
+ * @since 0.6.0
+ */
+ int getY() const A_WARN_UNUSED;
+
+ /**
+ * Mouse input event types. This enum partially corresponds
+ * to the enum with event types in MouseEvent for easy mapping.
+ */
+ enum
+ {
+ MOVED = 0,
+ PRESSED,
+ RELEASED,
+ WHEEL_MOVED_DOWN,
+ WHEEL_MOVED_UP
+ };
+
+ /**
+ * Mouse button types.
+ */
+ enum
+ {
+ EMPTY = 0,
+ LEFT,
+ RIGHT,
+ MIDDLE
+ };
+
+ protected:
+ /**
+ * Holds the type of the mouse input.
+ */
+ unsigned int mType;
+
+ /**
+ * Holds the button of the mouse input.
+ */
+ unsigned int mButton;
+
+ /**
+ * Holds the timestamp of the mouse input. Used to
+ * check for double clicks.
+ */
+ int mTimeStamp;
+
+ /**
+ * Holds the x coordinate of the mouse input.
+ */
+ int mX;
+
+ /**
+ * Holds the y coordinate of the mouse input.
+ */
+ int mY;
+ };
+} // namespace gcn
+
+#endif // end GCN_MOUSEINPUT_HPP
diff --git a/src/gui/base/mouselistener.hpp b/src/gui/base/mouselistener.hpp
new file mode 100644
index 000000000..32486e56f
--- /dev/null
+++ b/src/gui/base/mouselistener.hpp
@@ -0,0 +1,196 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_MOUSELISTENER_HPP
+#define GCN_MOUSELISTENER_HPP
+
+#include "gui/base/mouseevent.hpp"
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ /**
+ * Interface for listening for mouse events from widgets.
+ *
+ * @see Widget::addMouseListener, Widget::removeMouseListener
+ * @since 0.1.0
+ */
+ class MouseListener
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~MouseListener()
+ { }
+
+ /**
+ * Called when the mouse has entered into the widget area.
+ *
+ * @param mouseEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mouseEntered(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ /**
+ * Called when the mouse has exited the widget area.
+ *
+ * @param mouseEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mouseExited(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ /**
+ * Called when a mouse button has been pressed on the widget area.
+ *
+ * NOTE: A mouse press is NOT equal to a mouse click.
+ * Use mouseClickMessage to check for mouse clicks.
+ *
+ * @param mouseEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mousePressed(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ /**
+ * Called when a mouse button has been released on the widget area.
+ *
+ * @param mouseEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mouseReleased(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ /**
+ * Called when a mouse button is pressed and released (clicked) on
+ * the widget area.
+ *
+ * @param mouseEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mouseClicked(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ /**
+ * Called when the mouse wheel has moved up on the widget area.
+ *
+ * @param mouseEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mouseWheelMovedUp(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ /**
+ * Called when the mouse wheel has moved down on the widget area.
+ *
+ * @param mousEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mouseWheelMovedDown(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ /**
+ * Called when the mouse has moved in the widget area and no mouse button
+ * has been pressed (i.e no widget is being dragged).
+ *
+ * @param mouseEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mouseMoved(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ /**
+ * Called when the mouse has moved and the mouse has previously been
+ * pressed on the widget.
+ *
+ * @param mouseEvent Describes the event.
+ * @since 0.6.0
+ */
+ virtual void mouseDragged(MouseEvent& mouseEvent A_UNUSED)
+ {
+ }
+
+ protected:
+ /**
+ * Constructor.
+ *
+ * You should not be able to make an instance of MouseListener,
+ * therefore its constructor is protected.
+ */
+ MouseListener()
+ { }
+ };
+} // namespace gcn
+
+#endif // end GCN_MOUSELISTENER_HPP
diff --git a/src/gui/base/rectangle.cpp b/src/gui/base/rectangle.cpp
new file mode 100644
index 000000000..a29069b18
--- /dev/null
+++ b/src/gui/base/rectangle.cpp
@@ -0,0 +1,156 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/rectangle.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Rectangle::Rectangle()
+ : x(0),
+ y(0),
+ width(0),
+ height(0)
+ {
+ }
+
+ Rectangle::Rectangle(const int x_, const int y_,
+ const int width_, const int height_) :
+ x(x_),
+ y(y_),
+ width(width_),
+ height(height_)
+ {
+ }
+
+ void Rectangle::setAll(int x_, int y_, int width_, int height_)
+ {
+ x = x_;
+ y = y_;
+ width = width_;
+ height = height_;
+ }
+
+ bool Rectangle::isIntersecting(const Rectangle& rectangle) const
+ {
+ int x_ = x;
+ int y_ = y;
+ int width_ = width;
+ int height_ = height;
+
+ x_ -= rectangle.x;
+ y_ -= rectangle.y;
+
+ if (x_ < 0)
+ {
+ width_ += x_;
+// x_ = 0;
+ }
+ else if (x_ + width_ > rectangle.width)
+ {
+ width_ = rectangle.width - x_;
+ }
+
+ if (y_ < 0)
+ {
+ height_ += y_;
+// y_ = 0;
+ }
+ else if (y_ + height_ > rectangle.height)
+ {
+ height_ = rectangle.height - y_;
+ }
+
+ if (width_ <= 0 || height_ <= 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ bool Rectangle::isPointInRect(int x_, int y_) const
+ {
+ return x_ >= x
+ && y_ >= y
+ && x_ < x + width
+ && y_ < y + height;
+ }
+
+ std::ostream& operator<<(std::ostream& out,
+ const Rectangle& rectangle)
+ {
+ out << "Rectangle [x = " << rectangle.x
+ << ", y = " << rectangle.y
+ << ", width = " << rectangle.width
+ << ", height = " << rectangle.height
+ << "]";
+
+ return out;
+ }
+} // namespace gcn
diff --git a/src/gui/base/rectangle.hpp b/src/gui/base/rectangle.hpp
new file mode 100644
index 000000000..b8503db98
--- /dev/null
+++ b/src/gui/base/rectangle.hpp
@@ -0,0 +1,159 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_RECTANGLE_HPP
+#define GCN_RECTANGLE_HPP
+
+#include <iostream>
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ /**
+ * Represents a rectangle.
+ *
+ * @since 0.1.0
+ */
+ class Rectangle
+ {
+ public:
+ /**
+ * Constructor. The default rectangle is an empty rectangle
+ * at the coordinates (0,0).
+ */
+ Rectangle();
+
+ /**
+ * Constructor.
+ *
+ * @param x The x coordinate of the rectangle.
+ * @param y The y coordinate of the rectangle.
+ * @param width The width of the rectangle.
+ * @param height The height of the rectangle.
+ * @since 0.1.0
+ */
+ Rectangle(const int x, const int y, const int width, const int height);
+
+ /**
+ * Sets the dimension of a rectangle.
+ *
+ * @param x The x coordinate of the rectangle.
+ * @param y The y coordinate of the rectangle.
+ * @param width The width of the rectangle.
+ * @param height The height of the rectangle.
+ * @since 0.1.0
+ */
+ void setAll(int x, int y, int width, int height);
+
+ /**
+ * Checks if another rectangle intersects with the rectangle.
+ *
+ * @param rectangle Another rectangle to check for intersection.
+ * @return True if the rectangles intersect, false otherwise.
+ * @since 0.1.0
+ */
+ bool isIntersecting(const Rectangle& rectangle) const A_WARN_UNUSED;
+
+ /**
+ * Checks if a point is inside the rectangle
+ *
+ * @param x The x coordinate of the point.
+ * @param y The y coordinate of the point.
+ * @return True if the point is inside the rectangle.
+ * @since 0.1.0
+ */
+ bool isPointInRect(int x, int y) const A_WARN_UNUSED;
+
+ /**
+ * Output operator for output.
+ *
+ * @param out The stream to output to.
+ * @param rectangle The rectangle to output.
+ */
+ friend std::ostream& operator<<(std::ostream& out,
+ const Rectangle& rectangle);
+
+ /**
+ * Holds the x coordinate of the rectangle.
+ */
+ int x;
+
+ /**
+ * Holds the x coordinate of the rectangle.
+ */
+ int y;
+
+ /**
+ * Holds the width of the rectangle.
+ */
+ int width;
+
+ /**
+ * Holds the height of the rectangle.
+ */
+ int height;
+ };
+} // namespace gcn
+
+#endif // end GCN_RECTANGEL_HPP
diff --git a/src/gui/base/sdl/sdlpixel.hpp b/src/gui/base/sdl/sdlpixel.hpp
new file mode 100644
index 000000000..06a22f65f
--- /dev/null
+++ b/src/gui/base/sdl/sdlpixel.hpp
@@ -0,0 +1,306 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_SDLPIXEL_HPP
+#define GCN_SDLPIXEL_HPP
+
+#include "SDL.h"
+#include "gui/base/color.hpp"
+
+namespace gcn
+{
+
+ /**
+ * Checks a pixels color of an SDL_Surface.
+ *
+ * @param surface an SDL_Surface where to check for a pixel color.
+ * @param x the x coordinate on the surface.
+ * @param y the y coordinate on the surface.
+ * @return a color of a pixel.
+ */
+ inline const Color SDLgetPixel(SDL_Surface* surface, int x, int y)
+ {
+ if (!surface)
+ return Color(0, 0, 0, 0);
+
+ int bpp = surface->format->BytesPerPixel;
+
+ SDL_LockSurface(surface);
+
+ Uint8 *p = static_cast<uint8_t*>(surface->pixels)
+ + y * surface->pitch + x * bpp;
+
+ unsigned int color = 0;
+
+ switch (bpp)
+ {
+ case 1:
+ color = *p;
+ break;
+
+ case 2:
+ color = *reinterpret_cast<Uint16*>(p);
+ break;
+
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ color = p[0] << 16 | p[1] << 8 | p[2];
+#else
+ color = p[0] | p[1] << 8 | p[2] << 16;
+#endif
+ break;
+
+ case 4:
+ color = *reinterpret_cast<Uint32*>(p);
+ break;
+
+ default:
+ color = *p;
+ break;
+ }
+
+ unsigned char r, g, b, a;
+
+ SDL_GetRGBA(color, surface->format, &r, &g, &b, &a);
+ SDL_UnlockSurface(surface);
+
+ return Color(r, g, b, a);
+ }
+
+ /**
+ * Puts a pixel on an SDL_Surface.
+ *
+ * @param x the x coordinate on the surface.
+ * @param y the y coordinate on the surface.
+ * @param color the color the pixel should be in.
+ */
+ inline void SDLputPixel(SDL_Surface* surface, int x, int y,
+ const Color& color)
+ {
+ if (!surface)
+ return;
+
+ int bpp = surface->format->BytesPerPixel;
+
+ SDL_LockSurface(surface);
+
+ Uint8 *p = static_cast<uint8_t*>(surface->pixels)
+ + y * surface->pitch + x * bpp;
+
+ Uint32 pixel = SDL_MapRGB(surface->format,
+ static_cast<uint8_t>(color.r), static_cast<uint8_t>(color.g),
+ static_cast<uint8_t>(color.b));
+
+ switch (bpp)
+ {
+ case 1:
+ *p = static_cast<uint8_t>(pixel);
+ break;
+
+ case 2:
+ *reinterpret_cast<uint16_t*>(p) = static_cast<uint16_t>(pixel);
+ break;
+
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ p[0] = static_cast<uint8_t>((pixel >> 16) & 0xff);
+ p[1] = static_cast<uint8_t>((pixel >> 8) & 0xff);
+ p[2] = static_cast<uint8_t>((pixel) & 0xff);
+#else
+ p[0] = static_cast<uint8_t>((pixel) & 0xff);
+ p[1] = static_cast<uint8_t>((pixel >> 8) & 0xff);
+ p[2] = static_cast<uint8_t>((pixel >> 16) & 0xff);
+#endif
+ break;
+
+ case 4:
+ *reinterpret_cast<Uint32*>(p) = pixel;
+ break;
+
+ default:
+ break;
+ }
+
+ SDL_UnlockSurface(surface);
+ }
+
+ /**
+ * Blends two 32 bit colors together.
+ *
+ * @param src the source color.
+ * @param dst the destination color.
+ * @param a alpha.
+ */
+ inline unsigned int SDLAlpha32(unsigned int src, unsigned int dst,
+ unsigned char a)
+ {
+ unsigned int b = ((src & 0xff) * a + (dst & 0xff) * (255 - a)) >> 8;
+ unsigned int g = ((src & 0xff00) * a + (dst & 0xff00)
+ * (255 - a)) >> 8;
+ unsigned int r = ((src & 0xff0000) * a + (dst & 0xff0000)
+ * (255 - a)) >> 8;
+
+ return (b & 0xff) | (g & 0xff00) | (r & 0xff0000);
+ }
+
+ /**
+ * Blends two 16 bit colors together.
+ *
+ * @param src the source color.
+ * @param dst the destination color.
+ * @param a alpha.
+ */
+ inline unsigned short SDLAlpha16(unsigned short src, unsigned short dst,
+ unsigned char a, const SDL_PixelFormat *f)
+ {
+ unsigned int b = ((src & f->Rmask) * a + (dst & f->Rmask)
+ * (255 - a)) >> 8;
+ unsigned int g = ((src & f->Gmask) * a + (dst & f->Gmask)
+ * (255 - a)) >> 8;
+ unsigned int r = ((src & f->Bmask) * a + (dst & f->Bmask)
+ * (255 - a)) >> 8;
+
+ return static_cast<unsigned short>((b & f->Rmask)
+ | (g & f->Gmask) | (r & f->Bmask));
+ }
+
+ /*
+ typedef struct{
+ SDL_Palette *palette;
+ Uint8 BitsPerPixel;
+ Uint8 BytesPerPixel;
+ Uint32 Rmask, Gmask, Bmask, Amask;
+ Uint8 Rshift, Gshift, Bshift, Ashift;
+ Uint8 Rloss, Gloss, Bloss, Aloss;
+ Uint32 colorkey;
+ Uint8 alpha;
+ } SDL_PixelFormat;
+ */
+
+ /**
+ * Puts a pixel on an SDL_Surface with alpha
+ *
+ * @param x the x coordinate on the surface.
+ * @param y the y coordinate on the surface.
+ * @param color the color the pixel should be in.
+ */
+ inline void SDLputPixelAlpha(SDL_Surface* surface, int x, int y,
+ const Color& color)
+ {
+ int bpp = surface->format->BytesPerPixel;
+
+ SDL_LockSurface(surface);
+
+ Uint8 *p = static_cast<uint8_t*>(surface->pixels)
+ + y * surface->pitch + x * bpp;
+
+ Uint32 pixel = SDL_MapRGB(surface->format,
+ static_cast<uint8_t>(color.r),
+ static_cast<uint8_t>(color.g),
+ static_cast<uint8_t>(color.b));
+
+ switch (bpp)
+ {
+ case 1:
+ *p = static_cast<uint8_t>(pixel);
+ break;
+
+ case 2:
+ *reinterpret_cast<Uint16*>(p) = SDLAlpha16(
+ static_cast<unsigned short>(pixel),
+ *reinterpret_cast<unsigned short*>(p),
+ static_cast<unsigned char>(color.a), surface->format);
+ break;
+
+ case 3:
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ p[2] = static_cast<uint8_t>((p[2] * (255 - color.a)
+ + color.b * color.a) >> 8);
+ p[1] = static_cast<uint8_t>((p[1] * (255 - color.a)
+ + color.g * color.a) >> 8);
+ p[0] = static_cast<uint8_t>((p[0] * (255 - color.a)
+ + color.r * color.a) >> 8);
+#else
+ p[0] = static_cast<uint8_t>((p[0] * (255 - color.a)
+ + color.b * color.a) >> 8);
+ p[1] = static_cast<uint8_t>((p[1] * (255 - color.a)
+ + color.g * color.a) >> 8);
+ p[2] = static_cast<uint8_t>((p[2] * (255 - color.a)
+ + color.r * color.a) >> 8);
+#endif
+ break;
+
+ case 4:
+ *reinterpret_cast<Uint32*>(p) = SDLAlpha32(pixel,
+ *reinterpret_cast<Uint32*>(p),
+ static_cast<unsigned char>(color.a));
+ break;
+ default:
+ break;
+ }
+
+ SDL_UnlockSurface(surface);
+ }
+} // namespace gcn
+
+#endif // end GCN_SDLPIXEL_HPP
diff --git a/src/gui/base/selectionevent.cpp b/src/gui/base/selectionevent.cpp
new file mode 100644
index 000000000..04318be06
--- /dev/null
+++ b/src/gui/base/selectionevent.cpp
@@ -0,0 +1,82 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/selectionevent.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ SelectionEvent::SelectionEvent(Widget *const source) :
+ Event(source)
+ {
+ }
+
+ SelectionEvent::~SelectionEvent()
+ {
+ }
+} // namespace gcn
diff --git a/src/gui/base/selectionevent.hpp b/src/gui/base/selectionevent.hpp
new file mode 100644
index 000000000..543b3a9ad
--- /dev/null
+++ b/src/gui/base/selectionevent.hpp
@@ -0,0 +1,98 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_SELECTIONEVENT_HPP
+#define GCN_SELECTIONEVENT_HPP
+
+#include "gui/base/event.hpp"
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ class Widget;
+
+ /**
+ * Represents a selection event.
+ *
+ * @author Olof Naessén
+ * @since 0.8.0
+ */
+ class SelectionEvent final: public Event
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param source source The widget of the selection event.
+ */
+ explicit SelectionEvent(Widget *const source);
+
+ /**
+ * Destructor.
+ */
+ virtual ~SelectionEvent();
+ };
+} // namespace gcn
+
+#endif // end GCN_SELECTIONEVENT_HPP
diff --git a/src/gui/base/selectionlistener.hpp b/src/gui/base/selectionlistener.hpp
new file mode 100644
index 000000000..b1a4d73ba
--- /dev/null
+++ b/src/gui/base/selectionlistener.hpp
@@ -0,0 +1,117 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_SELECTIONLISTENER_HPP
+#define GCN_SELECTIONLISTENER_HPP
+
+#include <string>
+
+#include "gui/base/selectionevent.hpp"
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ /**
+ * Interface for listening for selection events from widgets.
+ *
+ * @see ListBox::addSelectionListener,
+ * ListBox::removeSelectionListener,
+ * DropDown::addSelectionListener,
+ * DropDown::removeSelectionListener
+ * @author Olof Naessén
+ * @since 0.8.0
+ */
+ class SelectionListener
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~SelectionListener()
+ { }
+
+ /**
+ * Called when the value of a selection has been changed in a Widget.
+ * It is used to be able to recieve a notification that a value has
+ * been changed.
+ *
+ * @param event The event of the value change.
+ * @since 0.8.0
+ */
+ virtual void valueChanged(const SelectionEvent& event A_UNUSED)
+ { }
+
+ protected:
+ /**
+ * Constructor.
+ *
+ * You should not be able to make an instance of SelectionListener,
+ * therefore its constructor is protected.
+ */
+ SelectionListener()
+ { }
+ };
+} // namespace gcn
+
+#endif // end GCN_SELECTIONLISTENER_HPP
diff --git a/src/gui/base/widget.cpp b/src/gui/base/widget.cpp
new file mode 100644
index 000000000..2e8719446
--- /dev/null
+++ b/src/gui/base/widget.cpp
@@ -0,0 +1,695 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widget.hpp"
+
+#include "gui/base/actionevent.hpp"
+#include "gui/base/actionlistener.hpp"
+#include "gui/base/basiccontainer.hpp"
+#include "gui/base/deathlistener.hpp"
+#include "gui/base/event.hpp"
+#include "gui/base/exception.hpp"
+#include "gui/base/focushandler.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/keyinput.hpp"
+#include "gui/base/keylistener.hpp"
+#include "gui/base/mouseinput.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widgetlistener.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Font* Widget::mGlobalFont = nullptr;
+ std::list<Widget*> Widget::mWidgets;
+ std::set<Widget*> Widget::mWidgetsSet;
+
+ Widget::Widget() :
+ mMouseListeners(),
+ mKeyListeners(),
+ mActionListeners(),
+ mDeathListeners(),
+ mFocusListeners(),
+ mWidgetListeners(),
+ mForegroundColor(0x000000),
+ mBackgroundColor(0xffffff),
+ mBaseColor(0x808090),
+ mSelectionColor(0xc3d9ff),
+ mFocusHandler(nullptr),
+ mInternalFocusHandler(nullptr),
+ mParent(nullptr),
+ mDimension(),
+ mFrameSize(0),
+ mActionEventId(),
+ mFocusable(false),
+ mVisible(true),
+ mTabIn(true),
+ mTabOut(true),
+ mEnabled(true),
+ mId(),
+ mCurrentFont(nullptr)
+ {
+ mWidgets.push_back(this);
+ mWidgetsSet.insert(this);
+ }
+
+ Widget::~Widget()
+ {
+ for (DeathListenerIterator iter = mDeathListeners.begin();
+ iter != mDeathListeners.end();
+ ++iter)
+ {
+ Event event(this);
+ (*iter)->death(event);
+ }
+
+ _setFocusHandler(nullptr);
+
+ mWidgets.remove(this);
+ mWidgetsSet.erase(this);
+ }
+
+ void Widget::drawFrame(Graphics* graphics)
+ {
+ BLOCK_START("Widget::drawFrame")
+ const Color &faceColor = getBaseColor();
+ Color highlightColor = faceColor + Color(0x303030);
+ Color shadowColor = faceColor - Color(0x303030);
+ const int alpha = getBaseColor().a;
+ const int width = getWidth() + getFrameSize() * 2 - 1;
+ const int height = getHeight() + getFrameSize() * 2 - 1;
+ highlightColor.a = alpha;
+ shadowColor.a = alpha;
+
+ for (unsigned int i = 0; i < getFrameSize(); ++i)
+ {
+ graphics->setColor(shadowColor);
+ graphics->drawLine(i, i, width - i, i);
+ graphics->drawLine(i, i + 1, i, height - i - 1);
+ graphics->setColor(highlightColor);
+ graphics->drawLine(width - i, i + 1, width - i, height - i);
+ graphics->drawLine(i, height - i, width - i - 1, height - i);
+ }
+ BLOCK_END("Widget::drawFrame")
+ }
+
+ void Widget::_setParent(Widget* parent)
+ {
+ mParent = parent;
+ }
+
+ void Widget::setWidth(int width)
+ {
+ Rectangle newDimension = mDimension;
+ newDimension.width = width;
+
+ setDimension(newDimension);
+ }
+
+ void Widget::setHeight(int height)
+ {
+ Rectangle newDimension = mDimension;
+ newDimension.height = height;
+
+ setDimension(newDimension);
+ }
+
+ void Widget::setX(int x)
+ {
+ Rectangle newDimension = mDimension;
+ newDimension.x = x;
+
+ setDimension(newDimension);
+ }
+
+ void Widget::setY(int y)
+ {
+ Rectangle newDimension = mDimension;
+ newDimension.y = y;
+
+ setDimension(newDimension);
+ }
+
+ void Widget::setPosition(int x, int y)
+ {
+ Rectangle newDimension = mDimension;
+ newDimension.x = x;
+ newDimension.y = y;
+
+ setDimension(newDimension);
+ }
+
+ void Widget::setDimension(const Rectangle& dimension)
+ {
+ const Rectangle oldDimension = mDimension;
+ mDimension = dimension;
+
+ if (mDimension.width != oldDimension.width
+ || mDimension.height != oldDimension.height)
+ {
+ distributeResizedEvent();
+ }
+
+ if (mDimension.x != oldDimension.x
+ || mDimension.y != oldDimension.y)
+ {
+ distributeMovedEvent();
+ }
+ }
+
+ void Widget::setFrameSize(unsigned int frameSize)
+ {
+ mFrameSize = frameSize;
+ }
+
+ unsigned int Widget::getFrameSize() const
+ {
+ return mFrameSize;
+ }
+
+ const Rectangle& Widget::getDimension() const
+ {
+ return mDimension;
+ }
+
+ const std::string& Widget::getActionEventId() const
+ {
+ return mActionEventId;
+ }
+
+ void Widget::setActionEventId(const std::string& actionEventId)
+ {
+ mActionEventId = actionEventId;
+ }
+
+ bool Widget::isFocused() const
+ {
+ if (!mFocusHandler)
+ return false;
+
+ return (mFocusHandler->isFocused(this));
+ }
+
+ void Widget::setFocusable(bool focusable)
+ {
+ if (!focusable && isFocused())
+ {
+ mFocusHandler->focusNone();
+ }
+
+ mFocusable = focusable;
+ }
+
+ bool Widget::isFocusable() const
+ {
+ return mFocusable && isVisible() && isEnabled();
+ }
+
+ void Widget::requestFocus()
+ {
+ if (!mFocusHandler)
+ {
+ throw GCN_EXCEPTION("No focushandler set (did you add "
+ "the widget to the gui?).");
+ }
+
+ if (isFocusable())
+ mFocusHandler->requestFocus(this);
+ }
+
+ void Widget::requestMoveToTop()
+ {
+ if (mParent)
+ mParent->moveToTop(this);
+ }
+
+ void Widget::requestMoveToBottom()
+ {
+ if (mParent)
+ mParent->moveToBottom(this);
+ }
+
+ void Widget::setVisible(bool visible)
+ {
+ if (!visible && isFocused())
+ mFocusHandler->focusNone();
+
+ if (visible)
+ distributeShownEvent();
+ else
+ distributeHiddenEvent();
+
+ mVisible = visible;
+ }
+
+ void Widget::setBaseColor(const Color& color)
+ {
+ mBaseColor = color;
+ }
+
+ const Color& Widget::getBaseColor() const
+ {
+ return mBaseColor;
+ }
+
+ void Widget::setForegroundColor(const Color& color)
+ {
+ mForegroundColor = color;
+ }
+
+ const Color& Widget::getForegroundColor() const
+ {
+ return mForegroundColor;
+ }
+
+ void Widget::setBackgroundColor(const Color& color)
+ {
+ mBackgroundColor = color;
+ }
+
+ const Color& Widget::getBackgroundColor() const
+ {
+ return mBackgroundColor;
+ }
+
+ void Widget::setSelectionColor(const Color& color)
+ {
+ mSelectionColor = color;
+ }
+
+ const Color& Widget::getSelectionColor() const
+ {
+ return mSelectionColor;
+ }
+
+ void Widget::_setFocusHandler(FocusHandler* focusHandler)
+ {
+ if (mFocusHandler)
+ {
+ releaseModalFocus();
+ mFocusHandler->remove(this);
+ }
+
+ if (focusHandler)
+ focusHandler->add(this);
+
+ mFocusHandler = focusHandler;
+ }
+
+ FocusHandler* Widget::_getFocusHandler()
+ {
+ return mFocusHandler;
+ }
+
+ void Widget::addActionListener(ActionListener* actionListener)
+ {
+ mActionListeners.push_back(actionListener);
+ }
+
+ void Widget::removeActionListener(ActionListener* actionListener)
+ {
+ mActionListeners.remove(actionListener);
+ }
+
+ void Widget::addDeathListener(DeathListener* deathListener)
+ {
+ mDeathListeners.push_back(deathListener);
+ }
+
+ void Widget::removeDeathListener(DeathListener* deathListener)
+ {
+ mDeathListeners.remove(deathListener);
+ }
+
+ void Widget::addKeyListener(KeyListener* keyListener)
+ {
+ mKeyListeners.push_back(keyListener);
+ }
+
+ void Widget::removeKeyListener(KeyListener* keyListener)
+ {
+ mKeyListeners.remove(keyListener);
+ }
+
+ void Widget::addFocusListener(FocusListener* focusListener)
+ {
+ mFocusListeners.push_back(focusListener);
+ }
+
+ void Widget::removeFocusListener(FocusListener* focusListener)
+ {
+ mFocusListeners.remove(focusListener);
+ }
+
+ void Widget::addMouseListener(MouseListener* mouseListener)
+ {
+ mMouseListeners.push_back(mouseListener);
+ }
+
+ void Widget::removeMouseListener(MouseListener* mouseListener)
+ {
+ mMouseListeners.remove(mouseListener);
+ }
+
+ void Widget::addWidgetListener(WidgetListener* widgetListener)
+ {
+ mWidgetListeners.push_back(widgetListener);
+ }
+
+ void Widget::removeWidgetListener(WidgetListener* widgetListener)
+ {
+ mWidgetListeners.remove(widgetListener);
+ }
+
+ void Widget::getAbsolutePosition(int& x, int& y) const
+ {
+ if (!mParent)
+ {
+ x = mDimension.x;
+ y = mDimension.y;
+ return;
+ }
+
+ int parentX;
+ int parentY;
+
+ mParent->getAbsolutePosition(parentX, parentY);
+
+ const Rectangle &rect = mParent->getChildrenArea();
+ x = parentX + mDimension.x + rect.x;
+ y = parentY + mDimension.y + rect.y;
+ }
+
+ Font* Widget::getFont() const
+ {
+ if (!mCurrentFont)
+ return mGlobalFont;
+ return mCurrentFont;
+ }
+
+ void Widget::setGlobalFont(Font* font)
+ {
+ mGlobalFont = font;
+
+ for (std::list<Widget*>::const_iterator iter = mWidgets.begin();
+ iter != mWidgets.end(); ++iter)
+ {
+ if (!(*iter)->mCurrentFont)
+ (*iter)->fontChanged();
+ }
+ }
+
+ void Widget::setFont(Font* font)
+ {
+ mCurrentFont = font;
+ fontChanged();
+ }
+
+ bool Widget::widgetExists(const Widget* widget)
+ {
+ return mWidgetsSet.find(const_cast<Widget*>(widget))
+ != mWidgetsSet.end();
+ }
+
+ bool Widget::isTabInEnabled() const
+ {
+ return mTabIn;
+ }
+
+ void Widget::setTabInEnabled(bool enabled)
+ {
+ mTabIn = enabled;
+ }
+
+ bool Widget::isTabOutEnabled() const
+ {
+ return mTabOut;
+ }
+
+ void Widget::setTabOutEnabled(bool enabled)
+ {
+ mTabOut = enabled;
+ }
+
+ void Widget::setSize(int width, int height)
+ {
+ Rectangle newDimension = mDimension;
+ newDimension.width = width;
+ newDimension.height = height;
+
+ setDimension(newDimension);
+ }
+
+ void Widget::setEnabled(bool enabled)
+ {
+ mEnabled = enabled;
+ }
+
+ bool Widget::isEnabled() const
+ {
+ return mEnabled && isVisible();
+ }
+
+ void Widget::requestModalFocus()
+ {
+ if (!mFocusHandler)
+ {
+ throw GCN_EXCEPTION("No focushandler set (did you add "
+ "the widget to the gui?).");
+ }
+
+ mFocusHandler->requestModalFocus(this);
+ }
+
+ void Widget::requestModalMouseInputFocus()
+ {
+ if (!mFocusHandler)
+ {
+ throw GCN_EXCEPTION("No focushandler set (did you add "
+ "the widget to the gui?).");
+ }
+
+ mFocusHandler->requestModalMouseInputFocus(this);
+ }
+
+ void Widget::releaseModalFocus()
+ {
+ if (!mFocusHandler)
+ return;
+
+ mFocusHandler->releaseModalFocus(this);
+ }
+
+ void Widget::releaseModalMouseInputFocus()
+ {
+ if (!mFocusHandler)
+ return;
+
+ mFocusHandler->releaseModalMouseInputFocus(this);
+ }
+
+ bool Widget::isModalFocused() const
+ {
+ if (!mFocusHandler)
+ {
+ throw GCN_EXCEPTION("No focushandler set (did you add "
+ "the widget to the gui?).");
+ }
+
+ if (mParent)
+ {
+ return (mFocusHandler->getModalFocused() == this)
+ || mParent->isModalFocused();
+ }
+
+ return mFocusHandler->getModalFocused() == this;
+ }
+
+ bool Widget::isModalMouseInputFocused() const
+ {
+ if (!mFocusHandler)
+ {
+ throw GCN_EXCEPTION("No focushandler set (did you add "
+ "the widget to the gui?).");
+ }
+
+ if (mParent)
+ {
+ return (mFocusHandler->getModalMouseInputFocused() == this)
+ || mParent->isModalMouseInputFocused();
+ }
+
+ return mFocusHandler->getModalMouseInputFocused() == this;
+ }
+
+ Widget *Widget::getWidgetAt(int x A_UNUSED, int y A_UNUSED)
+ {
+ return nullptr;
+ }
+
+ const std::list<MouseListener*>& Widget::_getMouseListeners()
+ {
+ return mMouseListeners;
+ }
+
+ const std::list<KeyListener*>& Widget::_getKeyListeners()
+ {
+ return mKeyListeners;
+ }
+
+ const std::list<FocusListener*>& Widget::_getFocusListeners()
+ {
+ return mFocusListeners;
+ }
+
+ Rectangle Widget::getChildrenArea()
+ {
+ return Rectangle(0, 0, 0, 0);
+ }
+
+ FocusHandler* Widget::_getInternalFocusHandler()
+ {
+ return mInternalFocusHandler;
+ }
+
+ void Widget::setInternalFocusHandler(FocusHandler* focusHandler)
+ {
+ mInternalFocusHandler = focusHandler;
+ }
+
+ void Widget::setId(const std::string& id)
+ {
+ mId = id;
+ }
+
+ const std::string& Widget::getId()
+ {
+ return mId;
+ }
+
+ void Widget::distributeResizedEvent()
+ {
+ for (WidgetListenerIterator iter = mWidgetListeners.begin();
+ iter != mWidgetListeners.end();
+ ++ iter)
+ {
+ Event event(this);
+ (*iter)->widgetResized(event);
+ }
+ }
+
+ void Widget::distributeMovedEvent()
+ {
+ for (WidgetListenerIterator iter = mWidgetListeners.begin();
+ iter != mWidgetListeners.end();
+ ++ iter)
+ {
+ Event event(this);
+ (*iter)->widgetMoved(event);
+ }
+ }
+
+ void Widget::distributeHiddenEvent()
+ {
+ for (WidgetListenerIterator iter = mWidgetListeners.begin();
+ iter != mWidgetListeners.end();
+ ++ iter)
+ {
+ Event event(this);
+ (*iter)->widgetHidden(event);
+ }
+ }
+
+ void Widget::distributeActionEvent()
+ {
+ for (ActionListenerIterator iter = mActionListeners.begin();
+ iter != mActionListeners.end();
+ ++iter)
+ {
+ ActionEvent actionEvent(this, mActionEventId);
+ (*iter)->action(actionEvent);
+ }
+ }
+
+ void Widget::distributeShownEvent()
+ {
+ for (WidgetListenerIterator iter = mWidgetListeners.begin();
+ iter != mWidgetListeners.end();
+ ++iter)
+ {
+ Event event(this);
+ (*iter)->widgetShown(event);
+ }
+ }
+
+ void Widget::showPart(Rectangle rectangle)
+ {
+ if (mParent)
+ mParent->showWidgetPart(this, rectangle);
+ }
+} // namespace gcn
diff --git a/src/gui/base/widget.hpp b/src/gui/base/widget.hpp
new file mode 100644
index 000000000..fe02d3b14
--- /dev/null
+++ b/src/gui/base/widget.hpp
@@ -0,0 +1,1232 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_WIDGET_HPP
+#define GCN_WIDGET_HPP
+
+#include <list>
+#include <set>
+#include <string>
+
+#include "guichan/color.hpp"
+#include "guichan/rectangle.hpp"
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ class ActionListener;
+ class BasicContainer;
+ class DeathListener;
+ class FocusHandler;
+ class FocusListener;
+ class Font;
+ class Graphics;
+ class KeyInput;
+ class KeyListener;
+ class MouseInput;
+ class MouseListener;
+ class WidgetListener;
+
+ /**
+ * Abstract class for widgets of Guichan. It contains basic functions
+ * every widget should have.
+ *
+ * NOTE: Functions begining with underscore "_" should not
+ * be overloaded unless you know what you are doing
+ *
+ * @author Olof Naessén
+ * @author Per Larsson.
+ * @since 0.1.0
+ */
+ class Widget
+ {
+ public:
+ /**
+ * Constructor. Resets member variables. Noteable, a widget is not
+ * focusable as default, therefore, widgets that are supposed to be
+ * focusable should overide this default in their own constructor.
+ */
+ Widget();
+
+ A_DELETE_COPY(Widget)
+
+ /**
+ * Default destructor.
+ */
+ virtual ~Widget();
+
+ /**
+ * Draws the widget. It is called by the parent widget when it is time
+ * for the widget to draw itself. The graphics object is set up so
+ * that all drawing is relative to the widget, i.e coordinate (0,0) is
+ * the top left corner of the widget. It is not possible to draw
+ * outside of a widget's dimension.
+ *
+ * @param graphics aA graphics object to draw with.
+ * @since 0.1.0
+ */
+ virtual void draw(Graphics* graphics) = 0;
+
+ /**
+ * Called when a widget is given a chance to draw a frame around itself.
+ * The frame is not considered a part of the widget, it only allows a frame
+ * to be drawn around the widget, thus a frame will never be included when
+ * calculating if a widget should receive events from user input. Also
+ * a widget's frame will never be included when calculating a widget's
+ * position.
+ *
+ * The size of the frame is calculated using the widget's frame size.
+ * If a widget has a frame size of 10 pixels than the area the drawFrame
+ * function can draw to will be the size of the widget with an additional
+ * extension of 10 pixels in each direction.
+ *
+ * An example when drawFrame is a useful function is if a widget needs
+ * a glow around itself.
+ *
+ * @param graphics A graphics object to draw with.
+ * @see setFrameSize, getFrameSize
+ * @since 0.8.0
+ */
+ virtual void drawFrame(Graphics* graphics);
+
+ /**
+ * Sets the size of the widget's frame. The frame is not considered a part of
+ * the widget, it only allows a frame to be drawn around the widget, thus a frame
+ * will never be included when calculating if a widget should receive events
+ * from user input. Also a widget's frame will never be included when calculating
+ * a widget's position.
+ *
+ * A frame size of 0 means that the widget has no frame. The default frame size
+ * is 0.
+ *
+ * @param frameSize The size of the widget's frame.
+ * @see getFrameSize, drawFrame
+ * @since 0.8.0
+ */
+ void setFrameSize(unsigned int frameSize);
+
+ /**
+ * Gets the size of the widget's frame. The frame is not considered a part of
+ * the widget, it only allows a frame to be drawn around the widget, thus a frame
+ * will never be included when calculating if a widget should receive events
+ * from user input. Also a widget's frame will never be included when calculating
+ * a widget's position.
+ *
+ * A frame size of 0 means that the widget has no frame. The default frame size
+ * is 0.
+ *
+ * @return The size of the widget's frame.
+ * @see setFrameSize, drawFrame
+ * @since 0.8.0
+ */
+ unsigned int getFrameSize() const A_WARN_UNUSED;
+
+ /**
+ * Called for all widgets in the gui each time Gui::logic is called.
+ * You can do logic stuff here like playing an animation.
+ *
+ * @see Gui::logic
+ * @since 0.1.0
+ */
+ virtual void logic()
+ { }
+
+ /**
+ * Gets the widget's parent container.
+ *
+ * @return The widget's parent container. NULL if the widget
+ * has no parent.
+ * @since 0.1.0
+ */
+ virtual Widget* getParent() const A_WARN_UNUSED
+ { return mParent; }
+
+ /**
+ * Sets the width of the widget.
+ *
+ * @param width The width of the widget.
+ * @see getWidth, setHeight, getHeight, setSize,
+ * setDimension, getDimensi
+ * @since 0.1.0
+ */
+ void setWidth(int width);
+
+ /**
+ * Gets the width of the widget.
+ *
+ * @return The width of the widget.
+ * @see setWidth, setHeight, getHeight, setSize,
+ * setDimension, getDimension
+ * @since 0.1.0
+ */
+ int getWidth() const A_WARN_UNUSED
+ { return mDimension.width; }
+
+ /**
+ * Sets the height of the widget.
+ *
+ * @param height The height of the widget.
+ * @see getHeight, setWidth, getWidth, setSize,
+ * setDimension, getDimension
+ * @since 0.1.0
+ */
+ void setHeight(int height);
+
+ /**
+ * Gets the height of the widget.
+ *
+ * @return The height of the widget.
+ * @see setHeight, setWidth, getWidth, setSize,
+ * setDimension, getDimension
+ * @since 0.1.0
+ */
+ int getHeight() const A_WARN_UNUSED
+ { return mDimension.height; }
+
+ /**
+ * Sets the size of the widget.
+ *
+ * @param width The width of the widget.
+ * @param height The height of the widget.
+ * @see setWidth, setHeight, getWidth, getHeight,
+ * setDimension, getDimension
+ * @since 0.1.0
+ */
+ void setSize(int width, int height);
+
+ /**
+ * Sets the x coordinate of the widget. The coordinate is
+ * relateive to the widget's parent.
+ *
+ * @param x The x coordinate of the widget.
+ * @see getX, setY, getY, setPosition, setDimension, getDimension
+ * @since 0.1.0
+ */
+ void setX(int x);
+
+ /**
+ * Gets the x coordinate of the widget. The coordinate is
+ * relative to the widget's parent.
+ *
+ * @return The x coordinate of the widget.
+ * @see setX, setY, getY, setPosition, setDimension, getDimension
+ * @since 0.1.0
+ */
+ int getX() const A_WARN_UNUSED
+ { return mDimension.x; }
+
+ /**
+ * Sets the y coordinate of the widget. The coordinate is
+ * relative to the widget's parent.
+ *
+ * @param y The y coordinate of the widget.
+ * @see setY, setX, getX, setPosition, setDimension, getDimension
+ * @since 0.1.0
+ */
+ void setY(int y);
+
+ /**
+ * Gets the y coordinate of the widget. The coordinate is
+ * relative to the widget's parent.
+ *
+ * @return The y coordinate of the widget.
+ * @see setY, setX, getX, setPosition, setDimension, getDimension
+ * @since 0.1.0
+ */
+ int getY() const A_WARN_UNUSED
+ { return mDimension.y; }
+
+ /**
+ * Sets position of the widget. The position is relative
+ * to the widget's parent.
+ *
+ * @param x The x coordinate of the widget.
+ * @param y The y coordinate of the widget.
+ * @see setX, getX, setY, getY, setDimension, getDimension
+ * @since 0.1.0
+ */
+ void setPosition(int x, int y);
+
+ /**
+ * Sets the dimension of the widget. The dimension is
+ * relative to the widget's parent.
+ *
+ * @param dimension The dimension of the widget.
+ * @see getDimension, setX, getX, setY, getY, setPosition
+ * @since 0.1.0
+ */
+ void setDimension(const Rectangle& dimension);
+
+ /**
+ * Gets the dimension of the widget. The dimension is
+ * relative to the widget's parent.
+ *
+ * @return The dimension of the widget.
+ * @see getDimension, setX, getX, setY, getY, setPosition
+ * @since 0.1.0
+ */
+ const Rectangle& getDimension() const A_WARN_UNUSED;
+
+ /**
+ * Sets the widget to be fosusable, or not.
+ *
+ * @param focusable True if the widget should be focusable,
+ * false otherwise.
+ * @see isFocusable
+ * @since 0.1.0
+ */
+ void setFocusable(bool focusable);
+
+ /**
+ * Checks if a widget is focsable.
+ *
+ * @return True if the widget should be focusable, false otherwise.
+ * @see setFocusable
+ * @since 0.1.0
+ */
+ bool isFocusable() const A_WARN_UNUSED;
+
+ /**
+ * Checks if the widget is focused.
+ *
+ * @return True if the widget is focused, false otherwise.
+ * @since 0.1.0
+ */
+ virtual bool isFocused() const A_WARN_UNUSED;
+
+ /**
+ * Sets the widget to enabled, or not. A disabled
+ * widget will never recieve mouse or key events.
+ *
+ * @param enabled True if widget should be enabled,
+ * false otherwise.
+ * @see isEnabled
+ * @since 0.1.0
+ */
+ void setEnabled(bool enabled);
+
+ /**
+ * Checks if the widget is enabled. A disabled
+ * widget will never recieve mouse or key events.
+ *
+ * @return True if widget is enabled, false otherwise.
+ * @see setEnabled
+ * @since 0.1.0
+ */
+ bool isEnabled() const A_WARN_UNUSED;
+
+ /**
+ * Sets the widget to be visible, or not.
+ *
+ * @param visible True if widget should be visible, false otherwise.
+ * @see isVisible
+ * @since 0.1.0
+ */
+ void setVisible(bool visible);
+
+ /**
+ * Checks if the widget is visible.
+ *
+ * @return True if widget is be visible, false otherwise.
+ * @see setVisible
+ * @since 0.1.0
+ */
+ bool isVisible() const A_WARN_UNUSED
+ { return mVisible && (!mParent || mParent->isVisible()); }
+
+ /**
+ * Sets the base color of the widget.
+ *
+ * @param color The baseground color.
+ * @see getBaseColor
+ * @since 0.1.0
+ */
+ void setBaseColor(const Color& color);
+
+ /**
+ * Gets the base color.
+ *
+ * @return The base color.
+ * @see setBaseColor
+ * @since 0.1.0
+ */
+ const Color& getBaseColor() const A_WARN_UNUSED;
+
+ /**
+ * Sets the foreground color.
+ *
+ * @param color The foreground color.
+ * @see getForegroundColor
+ * @since 0.1.0
+ */
+ void setForegroundColor(const Color& color);
+
+ /**
+ * Gets the foreground color.
+ *
+ * @see setForegroundColor
+ * @since 0.1.0
+ */
+ const Color& getForegroundColor() const A_WARN_UNUSED;
+
+ /**
+ * Sets the background color.
+ *
+ * @param color The background Color.
+ * @see setBackgroundColor
+ * @since 0.1.0
+ */
+ void setBackgroundColor(const Color& color);
+
+ /**
+ * Gets the background color.
+ *
+ * @see setBackgroundColor
+ * @since 0.1.0
+ */
+ const Color& getBackgroundColor() const A_WARN_UNUSED;
+
+ /**
+ * Sets the selection color.
+ *
+ * @param color The selection color.
+ * @see getSelectionColor
+ * @since 0.6.0
+ */
+ void setSelectionColor(const Color& color);
+
+ /**
+ * Gets the selection color.
+ *
+ * @return The selection color.
+ * @see setSelectionColor
+ * @since 0.6.0
+ */
+ const Color& getSelectionColor() const A_WARN_UNUSED;
+
+ /**
+ * Requests focus for the widget. A widget will only recieve focus
+ * if it is focusable.
+ */
+ virtual void requestFocus();
+
+ /**
+ * Requests a move to the top in the parent widget.
+ */
+ virtual void requestMoveToTop();
+
+ /**
+ * Requests a move to the bottom in the parent widget.
+ */
+ virtual void requestMoveToBottom();
+
+ /**
+ * Sets the focus handler to be used.
+ *
+ * WARNING: This function is used internally and should not
+ * be called or overloaded unless you know what you
+ * are doing.
+ *
+ * @param focusHandler The focus handler to use.
+ * @see _getFocusHandler
+ * @since 0.1.0
+ */
+ virtual void _setFocusHandler(FocusHandler* focusHandler);
+
+ /**
+ * Gets the focus handler used.
+ *
+ * WARNING: This function is used internally and should not
+ * be called or overloaded unless you know what you
+ * are doing.
+ *
+ * @return The focus handler used.
+ * @see _setFocusHandler
+ * @since 0.1.0
+ */
+ virtual FocusHandler* _getFocusHandler() A_WARN_UNUSED;
+
+ /**
+ * Adds an action listener to the widget. When an action event
+ * is fired by the widget the action listeners of the widget
+ * will get notified.
+ *
+ * @param actionListener The action listener to add.
+ * @see removeActionListener
+ * @since 0.1.0
+ */
+ void addActionListener(ActionListener* actionListener);
+
+ /**
+ * Removes an added action listener from the widget.
+ *
+ * @param actionListener The action listener to remove.
+ * @see addActionListener
+ * @since 0.1.0
+ */
+ void removeActionListener(ActionListener* actionListener);
+
+ /**
+ * Adds a death listener to the widget. When a death event is
+ * fired by the widget the death listeners of the widget will
+ * get notified.
+ *
+ * @param deathListener The death listener to add.
+ * @see removeDeathListener
+ * @since 0.1.0
+ */
+ void addDeathListener(DeathListener* deathListener);
+
+ /**
+ * Removes an added death listener from the widget.
+ *
+ * @param deathListener The death listener to remove.
+ * @see addDeathListener
+ * @since 0.1.0
+ */
+ void removeDeathListener(DeathListener* deathListener);
+
+ /**
+ * Adds a mouse listener to the widget. When a mouse event is
+ * fired by the widget the mouse listeners of the widget will
+ * get notified.
+ *
+ * @param mouseListener The mouse listener to add.
+ * @see removeMouseListener
+ * @since 0.1.0
+ */
+ void addMouseListener(MouseListener* mouseListener);
+
+ /**
+ * Removes an added mouse listener from the widget.
+ *
+ * @param mouseListener The mouse listener to remove.
+ * @see addMouseListener
+ * @since 0.1.0
+ */
+ void removeMouseListener(MouseListener* mouseListener);
+
+ /**
+ * Adds a key listener to the widget. When a key event is
+ * fired by the widget the key listeners of the widget will
+ * get notified.
+ *
+ * @param keyListener The key listener to add.
+ * @see removeKeyListener
+ * @since 0.1.0
+ */
+ void addKeyListener(KeyListener* keyListener);
+
+ /**
+ * Removes an added key listener from the widget.
+ *
+ * @param keyListener The key listener to remove.
+ * @see addKeyListener
+ * @since 0.1.0
+ */
+ void removeKeyListener(KeyListener* keyListener);
+
+ /**
+ * Adds a focus listener to the widget. When a focus event is
+ * fired by the widget the key listeners of the widget will
+ * get notified.
+ *
+ * @param focusListener The focus listener to add.
+ * @see removeFocusListener
+ * @since 0.7.0
+ */
+ void addFocusListener(FocusListener* focusListener);
+
+ /**
+ * Removes an added focus listener from the widget.
+ *
+ * @param focusListener The focus listener to remove.
+ * @see addFocusListener
+ * @since 0.7.0
+ */
+ void removeFocusListener(FocusListener* focusListener);
+
+ /**
+ * Adds a widget listener to the widget. When a widget event is
+ * fired by the widget the key listeners of the widget will
+ * get notified.
+ *
+ * @param widgetListener The widget listener to add.
+ * @see removeWidgetListener
+ * @since 0.8.0
+ */
+ void addWidgetListener(WidgetListener* widgetListener);
+
+ /**
+ * Removes an added widget listener from the widget.
+ *
+ * @param widgetListener The widget listener to remove.
+ * @see addWidgetListener
+ * @since 0.8.0
+ */
+ void removeWidgetListener(WidgetListener* widgetListener);
+
+ /**
+ * Sets the action event identifier of the widget. The identifier is
+ * used to be able to identify which action has occured.
+ *
+ * NOTE: An action event identifier should not be used to identify a
+ * certain widget but rather a certain event in your application.
+ * Several widgets can have the same action event identifer.
+ *
+ * @param actionEventId The action event identifier.
+ * @see getActionEventId
+ * @since 0.6.0
+ */
+ void setActionEventId(const std::string& actionEventId);
+
+ /**
+ * Gets the action event identifier of the widget.
+ *
+ * @return The action event identifier of the widget.
+ * @see setActionEventId
+ * @since 0.6.0
+ */
+ const std::string& getActionEventId() const;
+
+ /**
+ * Gets the absolute position on the screen for the widget.
+ *
+ * @param x The absolute x coordinate will be stored in this parameter.
+ * @param y The absolute y coordinate will be stored in this parameter.
+ * @since 0.1.0
+ */
+ virtual void getAbsolutePosition(int& x, int& y) const;
+
+ /**
+ * Sets the parent of the widget. A parent must be a BasicContainer.
+ *
+ * WARNING: This function is used internally and should not
+ * be called or overloaded unless you know what you
+ * are doing.
+ *
+ * @param parent The parent of the widget.
+ * @see getParent
+ * @since 0.1.0
+ */
+ virtual void _setParent(Widget* parent);
+
+ /**
+ * Gets the font set for the widget. If no font has been set,
+ * the global font will be returned. If no global font has been set,
+ * the default font will be returend.
+ *
+ * @return The font set for the widget.
+ * @see setFont, setGlobalFont
+ * @since 0.1.0
+ */
+ Font *getFont() const A_WARN_UNUSED;
+
+ /**
+ * Sets the global font to be used by default for all widgets.
+ *
+ * @param font The global font.
+ * @see getGlobalFont
+ * @since 0.1.0
+ */
+ static void setGlobalFont(Font* font);
+
+ /**
+ * Sets the font for the widget. If NULL is passed, the global font
+ * will be used.
+ *
+ * @param font The font to set for the widget.
+ * @see getFont
+ * @since 0.1.0
+ */
+ void setFont(Font* font);
+
+ /**
+ * Called when the font has changed. If the change is global,
+ * this function will only be called if the widget doesn't have a
+ * font already set.
+ *
+ * @since 0.1.0
+ */
+ virtual void fontChanged()
+ { }
+
+ /**
+ * Checks if a widget exists or not, that is if it still exists
+ * an instance of the object.
+ *
+ * @param widget The widget to check.
+ * @return True if an instance of the widget exists, false otherwise.
+ * @since 0.1.0
+ */
+ static bool widgetExists(const Widget* widget) A_WARN_UNUSED;
+
+ /**
+ * Checks if tab in is enabled. Tab in means that you can set focus
+ * to this widget by pressing the tab button. If tab in is disabled
+ * then the focus handler will skip this widget and focus the next
+ * in its focus order.
+ *
+ * @return True if tab in is enabled, false otherwise.
+ * @see setTabInEnabled
+ * @since 0.1.0
+ */
+ bool isTabInEnabled() const A_WARN_UNUSED;
+
+ /**
+ * Sets tab in enabled, or not. Tab in means that you can set focus
+ * to this widget by pressing the tab button. If tab in is disabled
+ * then the FocusHandler will skip this widget and focus the next
+ * in its focus order.
+ *
+ * @param enabled True if tab in should be enabled, false otherwise.
+ * @see isTabInEnabled
+ * @since 0.1.0
+ */
+ void setTabInEnabled(bool enabled);
+
+ /**
+ * Checks if tab out is enabled. Tab out means that you can lose
+ * focus to this widget by pressing the tab button. If tab out is
+ * disabled then the FocusHandler ignores tabbing and focus will
+ * stay with this widget.
+ *
+ * @return True if tab out is enabled, false otherwise.
+ * @see setTabOutEnabled
+ * @since 0.1.0
+ */
+ bool isTabOutEnabled() const A_WARN_UNUSED;
+
+ /**
+ * Sets tab out enabled. Tab out means that you can lose
+ * focus to this widget by pressing the tab button. If tab out is
+ * disabled then the FocusHandler ignores tabbing and focus will
+ * stay with this widget.
+ *
+ * @param enabled True if tab out should be enabled, false otherwise.
+ * @see isTabOutEnabled
+ * @since 0.1.0
+ */
+ void setTabOutEnabled(bool enabled);
+
+ /**
+ * Requests modal focus. When a widget has modal focus, only that
+ * widget and it's children may recieve input.
+ *
+ * @throws Exception if another widget already has modal focus.
+ * @see releaseModalFocus, isModalFocused
+ * @since 0.4.0
+ */
+ virtual void requestModalFocus();
+
+ /**
+ * Requests modal mouse input focus. When a widget has modal input focus
+ * that widget will be the only widget receiving input even if the input
+ * occurs outside of the widget and no matter what the input is.
+ *
+ * @throws Exception if another widget already has modal focus.
+ * @see releaseModalMouseInputFocus, isModalMouseInputFocused
+ * @since 0.6.0
+ */
+ virtual void requestModalMouseInputFocus();
+
+ /**
+ * Releases modal focus. Modal focus will only be released if the
+ * widget has modal focus.
+ *
+ * @see requestModalFocus, isModalFocused
+ * @since 0.4.0
+ */
+ virtual void releaseModalFocus();
+
+ /**
+ * Releases modal mouse input focus. Modal mouse input focus will only
+ * be released if the widget has modal mouse input focus.
+ *
+ * @see requestModalMouseInputFocus, isModalMouseInputFocused
+ * @since 0.6.0
+ */
+ virtual void releaseModalMouseInputFocus();
+
+ /**
+ * Checks if the widget or it's parent has modal focus.
+ *
+ * @return True if the widget has modal focus, false otherwise.
+ * @see requestModalFocus, releaseModalFocus
+ * @since 0.8.0
+ */
+ virtual bool isModalFocused() const A_WARN_UNUSED;
+
+ /**
+ * Checks if the widget or it's parent has modal mouse input focus.
+ *
+ * @return True if the widget has modal mouse input focus, false
+ * otherwise.
+ * @see requestModalMouseInputFocus, releaseModalMouseInputFocus
+ * @since 0.8.0
+ */
+ virtual bool isModalMouseInputFocused() const A_WARN_UNUSED;
+
+ /**
+ * Gets a widget from a certain position in the widget.
+ * This function is used to decide which gets mouse input,
+ * thus it can be overloaded to change that behaviour.
+ *
+ * NOTE: This always returns NULL if the widget is not
+ * a container.
+ *
+ * @param x The x coordinate of the widget to get.
+ * @param y The y coordinate of the widget to get.
+ * @return The widget at the specified coodinate, NULL
+ * if no widget is found.
+ * @since 0.6.0
+ */
+ virtual Widget *getWidgetAt(int x, int y) A_WARN_UNUSED;
+
+ /**
+ * Gets the mouse listeners of the widget.
+ *
+ * @return The mouse listeners of the widget.
+ * @since 0.6.0
+ */
+ virtual const std::list<MouseListener*>& _getMouseListeners()
+ A_WARN_UNUSED;
+
+ /**
+ * Gets the key listeners of the widget.
+ *
+ * @return The key listeners of the widget.
+ * @since 0.6.0
+ */
+ virtual const std::list<KeyListener*>& _getKeyListeners()
+ A_WARN_UNUSED;
+
+ /**
+ * Gets the focus listeners of the widget.
+ *
+ * @return The focus listeners of the widget.
+ * @since 0.7.0
+ */
+ virtual const std::list<FocusListener*>& _getFocusListeners()
+ A_WARN_UNUSED;
+
+ /**
+ * Gets the area of the widget occupied by the widget's children.
+ * By default this method returns an empty rectangle as not all
+ * widgets are containers. If you want to make a container this
+ * method should return the area where the children resides. This
+ * method is used when drawing children of a widget when computing
+ * clip rectangles for the children.
+ *
+ * An example of a widget that overloads this method is ScrollArea.
+ * A ScrollArea has a view of its contant and that view is the
+ * children area. The size of a ScrollArea's children area might
+ * vary depending on if the scroll bars of the ScrollArea is shown
+ * or not.
+ *
+ * @return The area of the widget occupied by the widget's children.
+ * @see BasicContainer
+ * @see BasicContainer::getChildrenArea
+ * @see BasicContainer::drawChildren
+ * @since 0.1.0
+ */
+ virtual Rectangle getChildrenArea() A_WARN_UNUSED;
+
+ /**
+ * Gets the internal focus handler used.
+ *
+ * @return the internalFocusHandler used. If no internal focus handler
+ * is used, NULL will be returned.
+ * @see setInternalFocusHandler
+ * @since 0.1.0
+ */
+ virtual FocusHandler* _getInternalFocusHandler() A_WARN_UNUSED;
+
+ /**
+ * Sets the internal focus handler. An internal focus handler is
+ * needed if both a widget in the widget and the widget itself
+ * should be foucsed at the same time.
+ *
+ * @param focusHandler The internal focus handler to be used.
+ * @see getInternalFocusHandler
+ * @since 0.1.0
+ */
+ void setInternalFocusHandler(FocusHandler* internalFocusHandler);
+
+ /**
+ * Moves a widget to the top of this widget. The moved widget will be
+ * drawn above all other widgets in this widget.
+ *
+ * @param widget The widget to move to the top.
+ * @see moveToBottom
+ * @since 0.1.0
+ */
+ virtual void moveToTop(Widget* widget A_UNUSED)
+ { }
+
+ /**
+ * Moves a widget in this widget to the bottom of this widget.
+ * The moved widget will be drawn below all other widgets in this widget.
+ *
+ * @param widget The widget to move to the bottom.
+ * @see moveToTop
+ * @since 0.1.0
+ */
+ virtual void moveToBottom(Widget* widget A_UNUSED)
+ { }
+
+ /**
+ * Focuses the next widget in the widget.
+ *
+ * @see moveToBottom
+ * @since 0.1.0
+ */
+ virtual void focusNext()
+ { }
+
+ /**
+ * Focuses the previous widget in the widget.
+ *
+ * @see moveToBottom
+ * @since 0.1.0
+ */
+ virtual void focusPrevious()
+ { }
+
+ /**
+ * Tries to show a specific part of a widget by moving it. Used if the
+ * widget should act as a container.
+ *
+ * @param widget The target widget.
+ * @param area The area to show.
+ * @since 0.1.0
+ */
+ virtual void showWidgetPart(Widget* widget A_UNUSED,
+ Rectangle area A_UNUSED)
+ { }
+
+ /**
+ * Sets an id of a widget. An id can be useful if a widget needs to be
+ * identified in a container. For example, if widgets are created by an
+ * XML document, a certain widget can be retrieved given that the widget
+ * has an id.
+ *
+ * @param id The id to set to the widget.
+ * @see getId, BasicContainer::findWidgetById
+ * @since 0.8.0
+ */
+ void setId(const std::string& id);
+
+ /**
+ * Gets the id of a widget. An id can be useful if a widget needs to be
+ * identified in a container. For example, if widgets are created by an
+ * XML document, a certain widget can be retrieved given that the widget
+ * has an id.
+ *
+ * @param id The id to set to the widget.
+ * @see setId, BasicContainer::findWidgetById
+ * @since 0.8.0
+ */
+ const std::string& getId() A_WARN_UNUSED;
+
+ /**
+ * Shows a certain part of a widget in the widget's parent.
+ * Used when widgets want a specific part to be visible in
+ * its parent. An example is a TextArea that wants a specific
+ * part of its text to be visible when a TextArea is a child
+ * of a ScrollArea.
+ *
+ * @param rectangle The rectangle to be shown.
+ * @since 0.8.0
+ */
+ virtual void showPart(Rectangle rectangle);
+
+ protected:
+ /**
+ * Distributes an action event to all action listeners
+ * of the widget.
+ *
+ * @since 0.8.0
+ */
+ void distributeActionEvent();
+
+ /**
+ * Distributes resized events to all of the widget's listeners.
+ *
+ * @since 0.8.0
+ */
+ void distributeResizedEvent();
+
+ /**
+ * Distributes moved events to all of the widget's listeners.
+ *
+ * @since 0.8.0
+ */
+ void distributeMovedEvent();
+
+ /**
+ * Distributes hidden events to all of the widget's listeners.
+ *
+ * @since 0.8.0
+ * @author Olof Naessén
+ */
+ void distributeHiddenEvent();
+
+ /**
+ * Distributes shown events to all of the widget's listeners.
+ *
+ * @since 0.8.0
+ * @author Olof Naessén
+ */
+ void distributeShownEvent();
+
+ /**
+ * Typdef.
+ */
+ typedef std::list<MouseListener*> MouseListenerList;
+
+ /**
+ * Typdef.
+ */
+ typedef MouseListenerList::iterator MouseListenerIterator;
+
+ /**
+ * Holds the mouse listeners of the widget.
+ */
+ MouseListenerList mMouseListeners;
+
+ /**
+ * Typdef.
+ */
+ typedef std::list<KeyListener*> KeyListenerList;
+
+ /**
+ * Holds the key listeners of the widget.
+ */
+ KeyListenerList mKeyListeners;
+
+ /**
+ * Typdef.
+ */
+ typedef KeyListenerList::iterator KeyListenerIterator;
+
+ /**
+ * Typdef.
+ */
+ typedef std::list<ActionListener*> ActionListenerList;
+
+ /**
+ * Holds the action listeners of the widget.
+ */
+ ActionListenerList mActionListeners;
+
+ /**
+ * Typdef.
+ */
+ typedef ActionListenerList::iterator ActionListenerIterator;
+
+ /**
+ * Typdef.
+ */
+ typedef std::list<DeathListener*> DeathListenerList;
+
+ /**
+ * Holds the death listeners of the widget.
+ */
+ DeathListenerList mDeathListeners;
+
+ /**
+ * Typdef.
+ */
+ typedef DeathListenerList::iterator DeathListenerIterator;
+
+ /**
+ * Typdef.
+ */
+ typedef std::list<FocusListener*> FocusListenerList;
+
+ /**
+ * Holds the focus listeners of the widget.
+ */
+ FocusListenerList mFocusListeners;
+
+ /**
+ * Typdef.
+ */
+ typedef FocusListenerList::iterator FocusListenerIterator;
+
+ typedef std::list<WidgetListener*> WidgetListenerList;
+
+ /**
+ * Holds the widget listeners of the widget.
+ */
+ WidgetListenerList mWidgetListeners;
+
+ /**
+ * Typdef.
+ */
+ typedef WidgetListenerList::iterator WidgetListenerIterator;
+
+ /**
+ * Holds the foreground color of the widget.
+ */
+ Color mForegroundColor;
+
+ /**
+ * Holds the background color of the widget.
+ */
+ Color mBackgroundColor;
+
+ /**
+ * Holds the base color of the widget.
+ */
+ Color mBaseColor;
+
+ /**
+ * Holds the selection color of the widget.
+ */
+ Color mSelectionColor;
+
+ /**
+ * Holds the focus handler used by the widget.
+ */
+ FocusHandler* mFocusHandler;
+
+ /**
+ * Holds the focus handler used by the widget. NULL
+ * if no internal focus handler is used.
+ */
+ FocusHandler* mInternalFocusHandler;
+
+ /**
+ * Holds the parent of the widget. NULL if the widget
+ * has no parent.
+ */
+ Widget* mParent;
+
+ /**
+ * Holds the dimension of the widget.
+ */
+ Rectangle mDimension;
+
+ /**
+ * Holds the frame size of the widget.
+ */
+ unsigned int mFrameSize;
+
+ /**
+ * Holds the action event of the widget.
+ */
+ std::string mActionEventId;
+
+ /**
+ * True if the widget focusable, false otherwise.
+ */
+ bool mFocusable;
+
+ /**
+ * True if the widget visible, false otherwise.
+ */
+ bool mVisible;
+
+ /**
+ * True if the widget has tab in enabled, false otherwise.
+ */
+ bool mTabIn;
+
+ /**
+ * True if the widget has tab in enabled, false otherwise.
+ */
+ bool mTabOut;
+
+ /**
+ * True if the widget is enabled, false otherwise.
+ */
+ bool mEnabled;
+
+ /**
+ * Holds the id of the widget.
+ */
+ std::string mId;
+
+ /**
+ * Holds the font used by the widget.
+ */
+ Font* mCurrentFont;
+
+ /**
+ * Holds the global font used by the widget.
+ */
+ static Font* mGlobalFont;
+
+ /**
+ * Holds a list of all instances of widgets.
+ */
+ static std::list<Widget*> mWidgets;
+
+ static std::set<Widget*> mWidgetsSet;
+ };
+} // namespace gcn
+
+#endif // end GCN_WIDGET_HPP
diff --git a/src/gui/base/widgetlistener.hpp b/src/gui/base/widgetlistener.hpp
new file mode 100644
index 000000000..3dd74bb4d
--- /dev/null
+++ b/src/gui/base/widgetlistener.hpp
@@ -0,0 +1,143 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_WIDGETLISTENER_HPP
+#define GCN_WIDGETLISTENER_HPP
+
+#include <string>
+
+#include "gui/base/event.hpp"
+
+#include "localconsts.h"
+
+namespace gcn
+{
+ /**
+ * Interface for listening for events from widgets. When a widget's size,
+ * location or visibility changes, the relevant method of the listener is
+ * invoked.
+ *
+ * @see Widget::addWidgetListener, Widget::removeWidgetListener
+ * @author Olof Naessén
+ * @since 0.8.0
+ */
+ class WidgetListener
+ {
+ public:
+ /**
+ * Destructor.
+ */
+ virtual ~WidgetListener()
+ { }
+
+ /**
+ * Invoked when a widget changes its size.
+ *
+ * @param event Describes the event.
+ * @since 0.8.0
+ */
+ virtual void widgetResized(const Event& event A_UNUSED)
+ { }
+
+ /**
+ * Invoked when a widget is moved.
+ *
+ * @param event Describes the event.
+ * @since 0.8.0
+ */
+ virtual void widgetMoved(const Event& event A_UNUSED)
+ { }
+
+ /**
+ * Invoked when a widget is hidden, i.e it's set to be
+ * not visible.
+ *
+ * @param event Describes the event.
+ * @since 0.8.0
+ */
+ virtual void widgetHidden(const Event& event A_UNUSED)
+ { }
+
+ /**
+ * Invoked when a widget is shown, i.e it's set to be
+ * visible.
+ *
+ * @param event Describes the event.
+ * @since 0.8.0
+ */
+ virtual void widgetShown(const Event& event A_UNUSED)
+ { }
+
+ protected:
+ /**
+ * Constructor.
+ *
+ * You should not be able to make an instance of WidgetListener,
+ * therefore its constructor is protected.
+ */
+ WidgetListener()
+ { }
+ };
+} // namespace gcn
+
+#endif // end GCN_WIDGETLISTENER_HPP
diff --git a/src/gui/base/widgets/button.cpp b/src/gui/base/widgets/button.cpp
new file mode 100644
index 000000000..a52bf2d78
--- /dev/null
+++ b/src/gui/base/widgets/button.cpp
@@ -0,0 +1,194 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/button.hpp"
+
+#include "gui/base/exception.hpp"
+#include "gui/base/font.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/key.hpp"
+#include "gui/base/mouseevent.hpp"
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Button::Button() :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ gcn::FocusListener(),
+ mCaption(),
+ mHasMouse(false),
+ mKeyPressed(false),
+ mMousePressed(false),
+ mAlignment(Graphics::CENTER),
+ mSpacing(4)
+ {
+ setFocusable(true);
+ adjustSize();
+ setFrameSize(1);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ addFocusListener(this);
+ }
+
+ Button::Button(const std::string& caption) :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ gcn::FocusListener(),
+ mCaption(caption),
+ mHasMouse(false),
+ mKeyPressed(false),
+ mMousePressed(false),
+ mAlignment(Graphics::CENTER),
+ mSpacing(4)
+ {
+ setFocusable(true);
+ adjustSize();
+ setFrameSize(1);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ addFocusListener(this);
+ }
+
+ void Button::setCaption(const std::string& caption)
+ {
+ mCaption = caption;
+ }
+
+ const std::string& Button::getCaption() const
+ {
+ return mCaption;
+ }
+
+ void Button::setAlignment(Graphics::Alignment alignment)
+ {
+ mAlignment = alignment;
+ }
+
+ Graphics::Alignment Button::getAlignment() const
+ {
+ return mAlignment;
+ }
+
+ void Button::setSpacing(unsigned int spacing)
+ {
+ mSpacing = spacing;
+ }
+
+ unsigned int Button::getSpacing() const
+ {
+ return mSpacing;
+ }
+
+ void Button::adjustSize()
+ {
+ }
+
+ bool Button::isPressed() const
+ {
+ if (mMousePressed)
+ return mHasMouse;
+ else
+ return mKeyPressed;
+ }
+
+ void Button::mousePressed(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.getButton() == MouseEvent::LEFT)
+ {
+ mMousePressed = true;
+ mouseEvent.consume();
+ }
+ }
+
+ void Button::mouseExited(MouseEvent& mouseEvent A_UNUSED)
+ {
+ mHasMouse = false;
+ }
+
+ void Button::mouseEntered(MouseEvent& mouseEvent A_UNUSED)
+ {
+ mHasMouse = true;
+ }
+
+ void Button::mouseDragged(MouseEvent& mouseEvent)
+ {
+ mouseEvent.consume();
+ }
+
+ void Button::focusLost(const Event& event A_UNUSED)
+ {
+ mMousePressed = false;
+ mKeyPressed = false;
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/button.hpp b/src/gui/base/widgets/button.hpp
new file mode 100644
index 000000000..4ae08eb16
--- /dev/null
+++ b/src/gui/base/widgets/button.hpp
@@ -0,0 +1,220 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_BUTTON_HPP
+#define GCN_BUTTON_HPP
+
+#include <string>
+
+#include "gui/base/focuslistener.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/keylistener.hpp"
+#include "gui/base/mouseevent.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widget.hpp"
+
+namespace gcn
+{
+ /**
+ * An implementation of a regular clickable button. A button is capable of
+ * displaying a caption.
+ *
+ * If a button is clicked an action event will be sent to all action listener's
+ * of the button.
+ *
+ * @see ImageButton
+ */
+ class Button : public Widget,
+ public MouseListener,
+ public KeyListener,
+ public FocusListener
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ Button();
+
+ /**
+ * Constructor. The button will be automatically resized
+ * to fit the caption.
+ *
+ * @param caption The caption of the button.
+ */
+ explicit Button(const std::string& caption);
+
+ A_DELETE_COPY(Button)
+
+ /**
+ * Sets the caption of the button. It's advisable to call
+ * adjustSize after setting of the caption to adjust the
+ * button's size to fit the caption.
+ *
+ * @param caption The caption of the button.
+ * @see getCaption, adjustSize
+ */
+ void setCaption(const std::string& caption);
+
+ /**
+ * Gets the caption of the button.
+ *
+ * @return The caption of the button.
+ */
+ const std::string& getCaption() const;
+
+ /**
+ * Sets the alignment of the caption. The alignment is relative
+ * to the center of the button.
+ *
+ * @param alignment The alignment of the caption.
+ * @see getAlignment, Graphics
+ */
+ void setAlignment(Graphics::Alignment alignment);
+
+ /**
+ * Gets the alignment of the caption.
+ *
+ * @return The alignment of the caption.
+ * @see setAlignment, Graphics
+ */
+ Graphics::Alignment getAlignment() const;
+
+ /**
+ * Sets the spacing between the border of the button and its caption.
+ *
+ * @param spacing The default value for spacing is 4 and can be changed
+ * using this method.
+ * @see getSpacing
+ */
+ void setSpacing(unsigned int spacing);
+
+ /**
+ * Gets the spacing between the border of the button and its caption.
+ *
+ * @return spacing.
+ * @see setSpacing
+ */
+ unsigned int getSpacing() const;
+
+ /**
+ * Adjusts the button's size to fit the caption.
+ */
+ void adjustSize();
+
+
+ // Inherited from FocusListener
+
+ virtual void focusLost(const Event& event);
+
+ // Inherited from MouseListener
+
+ virtual void mousePressed(MouseEvent& mouseEvent) override;
+
+ virtual void mouseEntered(MouseEvent& mouseEvent) override;
+
+ virtual void mouseExited(MouseEvent& mouseEvent) override;
+
+ virtual void mouseDragged(MouseEvent& mouseEvent) override;
+
+ protected:
+ /**
+ * Checks if the button is pressed. Convenient method to use
+ * when overloading the draw method of the button.
+ *
+ * @return True if the button is pressed, false otherwise.
+ */
+ bool isPressed() const;
+
+ /**
+ * Holds the caption of the button.
+ */
+ std::string mCaption;
+
+ /**
+ * True if the mouse is ontop of the button, false otherwise.
+ */
+ bool mHasMouse;
+
+ /**
+ * True if a key has been pressed, false otherwise.
+ */
+ bool mKeyPressed;
+
+ /**
+ * True if a mouse has been pressed, false otherwise.
+ */
+ bool mMousePressed;
+
+ /**
+ * Holds the alignment of the caption.
+ */
+ Graphics::Alignment mAlignment;
+
+ /**
+ * Holds the spacing between the border and the caption.
+ */
+ unsigned int mSpacing;
+ };
+} // namespace gcn
+
+#endif // end GCN_BUTTON_HPP
diff --git a/src/gui/base/widgets/checkbox.cpp b/src/gui/base/widgets/checkbox.cpp
new file mode 100644
index 000000000..908b4f509
--- /dev/null
+++ b/src/gui/base/widgets/checkbox.cpp
@@ -0,0 +1,154 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/checkbox.hpp"
+
+#include "gui/base/font.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/key.hpp"
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+
+ CheckBox::CheckBox() :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mSelected(false),
+ mCaption()
+ {
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+ }
+
+ CheckBox::CheckBox(const std::string &caption, bool selected) :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mSelected(selected),
+ mCaption()
+ {
+ setCaption(caption);
+
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+
+ adjustSize();
+ }
+
+ bool CheckBox::isSelected() const
+ {
+ return mSelected;
+ }
+
+ void CheckBox::setSelected(bool selected)
+ {
+ mSelected = selected;
+ }
+
+ const std::string &CheckBox::getCaption() const
+ {
+ return mCaption;
+ }
+
+ void CheckBox::setCaption(const std::string& caption)
+ {
+ mCaption = caption;
+ }
+
+ void CheckBox::keyPressed(KeyEvent& keyEvent A_UNUSED)
+ {
+ }
+
+ void CheckBox::mouseClicked(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.getButton() == MouseEvent::LEFT)
+ {
+ toggleSelected();
+ }
+ }
+
+ void CheckBox::mouseDragged(MouseEvent& mouseEvent)
+ {
+ mouseEvent.consume();
+ }
+
+ void CheckBox::adjustSize()
+ {
+ }
+
+ void CheckBox::toggleSelected()
+ {
+ mSelected = !mSelected;
+ distributeActionEvent();
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/checkbox.hpp b/src/gui/base/widgets/checkbox.hpp
new file mode 100644
index 000000000..c9b723879
--- /dev/null
+++ b/src/gui/base/widgets/checkbox.hpp
@@ -0,0 +1,180 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_CHECKBOX_HPP
+#define GCN_CHECKBOX_HPP
+
+#include <string>
+
+#include "gui/base/keylistener.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widget.hpp"
+
+namespace gcn
+{
+ /**
+ * An implementation of a check box where a user can select or deselect
+ * the check box and where the status of the check box is displayed to the user.
+ * A check box is capable of displaying a caption.
+ *
+ * If a check box's state changes an action event will be sent to all action
+ * listeners of the check box.
+ */
+ class CheckBox :
+ public Widget,
+ public MouseListener,
+ public KeyListener
+ {
+ public:
+ /**
+ * Contructor.
+ */
+ CheckBox();
+
+ /**
+ * Constructor. The check box will be automatically resized
+ * to fit the caption.
+ *
+ * @param caption The caption of the check box.
+ * @param marked True if the check box is selected, false otherwise.
+ */
+ CheckBox(const std::string &caption, bool selected = false);
+
+ A_DELETE_COPY(CheckBox)
+
+ /**
+ * Destructor.
+ */
+ virtual ~CheckBox()
+ { }
+
+ /**
+ * Checks if the check box is selected.
+ *
+ * @return True if the check box is selected, false otherwise.
+ * @see setSelected
+ */
+ bool isSelected() const;
+
+ /**
+ * Sets the check box to be selected or not.
+ *
+ * @param selected True if the check box should be set as selected.
+ * @see isSelected
+ */
+ void setSelected(bool selected);
+
+ /**
+ * Gets the caption of the check box.
+ *
+ * @return The caption of the check box.
+ * @see setCaption
+ */
+ const std::string &getCaption() const;
+
+ /**
+ * Sets the caption of the check box. It's advisable to call
+ * adjustSize after setting of the caption to adjust the
+ * check box's size to fit the caption.
+ *
+ * @param caption The caption of the check box.
+ * @see getCaption, adjustSize
+ */
+ void setCaption(const std::string& caption);
+
+ /**
+ * Adjusts the check box's size to fit the caption.
+ */
+ void adjustSize();
+
+ // Inherited from KeyListener
+
+ virtual void keyPressed(KeyEvent& keyEvent) override;
+
+ // Inherited from MouseListener
+
+ virtual void mouseClicked(MouseEvent& mouseEvent) override;
+
+ virtual void mouseDragged(MouseEvent& mouseEvent) override;
+
+
+ protected:
+ /**
+ * Toggles the check box between being selected and
+ * not being selected.
+ */
+ virtual void toggleSelected();
+
+ /**
+ * True if the check box is selected, false otherwise.
+ */
+ bool mSelected;
+
+ /**
+ * Holds the caption of the check box.
+ */
+ std::string mCaption;
+ };
+} // namespace gcn
+
+#endif // end GCN_CHECKBOX_HPP
diff --git a/src/gui/base/widgets/container.cpp b/src/gui/base/widgets/container.cpp
new file mode 100644
index 000000000..1e6de018b
--- /dev/null
+++ b/src/gui/base/widgets/container.cpp
@@ -0,0 +1,136 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/container.hpp"
+
+#include "gui/base/exception.hpp"
+#include "gui/base/graphics.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+
+ Container::Container() :
+ BasicContainer(),
+ mOpaque(true)
+ {
+ }
+
+ Container::~Container()
+ {
+ }
+
+ void Container::draw(Graphics* graphics)
+ {
+ BLOCK_START("Container::draw")
+ if (isOpaque())
+ {
+ graphics->setColor(getBaseColor());
+ graphics->fillRectangle(Rectangle(0, 0, getWidth(), getHeight()));
+ }
+
+ drawChildren(graphics);
+ BLOCK_END("Container::draw")
+ }
+
+ void Container::setOpaque(bool opaque)
+ {
+ mOpaque = opaque;
+ }
+
+ bool Container::isOpaque() const
+ {
+ return mOpaque;
+ }
+
+ void Container::add(Widget* widget)
+ {
+ BasicContainer::add(widget);
+ }
+
+ void Container::add(Widget* widget, int x, int y)
+ {
+ widget->setPosition(x, y);
+ BasicContainer::add(widget);
+ }
+
+ void Container::remove(Widget* widget)
+ {
+ BasicContainer::remove(widget);
+ }
+
+ void Container::clear()
+ {
+ BasicContainer::clear();
+ }
+
+ Widget* Container::findWidgetById(const std::string &id)
+ {
+ return BasicContainer::findWidgetById(id);
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/container.hpp b/src/gui/base/widgets/container.hpp
new file mode 100644
index 000000000..a5cbdb31b
--- /dev/null
+++ b/src/gui/base/widgets/container.hpp
@@ -0,0 +1,180 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_CONTAINER_HPP
+#define GCN_CONTAINER_HPP
+
+#include <list>
+
+#include "gui/base/basiccontainer.hpp"
+#include "gui/base/graphics.hpp"
+
+namespace gcn
+{
+ /**
+ * An implementation of a container able to contain other widgets. A widget's
+ * position in the container is relative to the container itself and not the screen.
+ * A container is the most common widget to use as the Gui's top widget as makes the Gui
+ * able to contain more than one widget.
+ *
+ * @see Gui::setTop
+ */
+ class Container: public BasicContainer
+ {
+ public:
+ /**
+ * Constructor. A container is opauqe as default, if you want a
+ * none opaque container call setQpaque(false).
+ *
+ * @see setOpaque, isOpaque
+ */
+ Container();
+
+ /**
+ * Destructor.
+ */
+ virtual ~Container();
+
+ /**
+ * Sets the container to be opaque or not. If the container
+ * is opaque its background will be drawn, if it's not opaque
+ * its background will not be drawn, and thus making the container
+ * completely transparent.
+ *
+ * NOTE: This is not the same as to set visibility. A non visible
+ * container will not itself nor will it draw its content.
+ *
+ * @param opaque True if the container should be opaque, false otherwise.
+ * @see isOpaque
+ */
+ void setOpaque(bool opaque);
+
+ /**
+ * Checks if the container is opaque or not.
+ *
+ * @return True if the container is opaque, false otherwise.
+ * @see setOpaque
+ */
+ bool isOpaque() const;
+
+ /**
+ * Adds a widget to the container.
+ *
+ * @param widget The widget to add.
+ * @see remove, clear
+ */
+ virtual void add(Widget* widget);
+
+ /**
+ * Adds a widget to the container and also specifies the widget's
+ * position in the container. The position is relative to the container
+ * and not relative to the screen.
+ *
+ * @param widget The widget to add.
+ * @param x The x coordinate for the widget.
+ * @param y The y coordinate for the widget.
+ * @see remove, clear
+ */
+ virtual void add(Widget* widget, int x, int y);
+
+ /**
+ * Removes a widget from the Container.
+ *
+ * @param widget The widget to remove.
+ * @throws Exception when the widget has not been added to the
+ * container.
+ * @see add, clear
+ */
+ virtual void remove(Widget* widget);
+
+ /**
+ * Clears the container of all widgets.
+ *
+ * @see add, remove
+ */
+ virtual void clear();
+
+ /**
+ * Finds a widget given an id.
+ *
+ * @param id The id to find a widget by.
+ * @return A widget with a corrosponding id, NULL if no widget
+ * is found.
+ * @see Widget::setId
+ */
+ virtual Widget* findWidgetById(const std::string &id);
+
+
+ // Inherited from Widget
+
+ virtual void draw(Graphics* graphics);
+
+ protected:
+ /**
+ * True if the container is opaque, false otherwise.
+ */
+ bool mOpaque;
+ };
+} // namespace gcn
+
+#endif // end GCN_CONTAINER_HPP
diff --git a/src/gui/base/widgets/label.cpp b/src/gui/base/widgets/label.cpp
new file mode 100644
index 000000000..42fcd78f4
--- /dev/null
+++ b/src/gui/base/widgets/label.cpp
@@ -0,0 +1,121 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/label.hpp"
+
+#include "gui/base/exception.hpp"
+#include "gui/base/font.hpp"
+#include "gui/base/graphics.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Label::Label() :
+ gcn::Widget(),
+ mCaption(),
+ mAlignment(Graphics::LEFT)
+ {
+ }
+
+ Label::Label(const std::string& caption) :
+ gcn::Widget(),
+ mCaption(caption),
+ mAlignment(Graphics::LEFT)
+ {
+ setWidth(getFont()->getWidth(caption));
+ setHeight(getFont()->getHeight());
+ }
+
+ const std::string &Label::getCaption() const
+ {
+ return mCaption;
+ }
+
+ void Label::setCaption(const std::string& caption)
+ {
+ mCaption = caption;
+ }
+
+ void Label::setAlignment(Graphics::Alignment alignment)
+ {
+ mAlignment = alignment;
+ }
+
+ Graphics::Alignment Label::getAlignment() const
+ {
+ return mAlignment;
+ }
+
+ void Label::draw(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void Label::adjustSize()
+ {
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/label.hpp b/src/gui/base/widgets/label.hpp
new file mode 100644
index 000000000..f1ef30b89
--- /dev/null
+++ b/src/gui/base/widgets/label.hpp
@@ -0,0 +1,154 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_LABEL_HPP
+#define GCN_LABEL_HPP
+
+#include <string>
+
+#include "gui/base/graphics.hpp"
+#include "gui/base/widget.hpp"
+
+namespace gcn
+{
+ /**
+ * Implementation of a label capable of displaying a caption.
+ */
+ class Label: public Widget
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ Label();
+
+ /**
+ * Constructor. The label will be automatically resized
+ * to fit the caption.
+ *
+ * @param caption The caption of the label.
+ */
+ explicit Label(const std::string& caption);
+
+ A_DELETE_COPY(Label)
+
+ /**
+ * Gets the caption of the label.
+ *
+ * @return The caption of the label.
+ * @see setCaption
+ */
+ const std::string &getCaption() const;
+
+ /**
+ * Sets the caption of the label. It's advisable to call
+ * adjustSize after setting of the caption to adjust the
+ * label's size to fit the caption.
+ *
+ * @param caption The caption of the label.
+ * @see getCaption, adjustSize
+ */
+ void setCaption(const std::string& caption);
+
+ /**
+ * Sets the alignment of the caption. The alignment is relative
+ * to the center of the label.
+ *
+ * @param alignemnt The alignment of the caption of the label.
+ * @see getAlignment, Graphics
+ */
+ void setAlignment(Graphics::Alignment alignment);
+
+ /**
+ * Gets the alignment of the caption. The alignment is relative to
+ * the center of the label.
+ *
+ * @return The alignment of caption of the label.
+ * @see setAlignmentm Graphics
+ */
+ Graphics::Alignment getAlignment() const;
+
+ /**
+ * Adjusts the label's size to fit the caption.
+ */
+ void adjustSize();
+
+
+ // Inherited from Widget
+
+ virtual void draw(Graphics* graphics);
+
+ protected:
+ /**
+ * Holds the caption of the label.
+ */
+ std::string mCaption;
+
+ /**
+ * Holds the alignment of the caption.
+ */
+ Graphics::Alignment mAlignment;
+ };
+} // namespace gcn
+
+#endif // end GCN_LABEL_HPP
diff --git a/src/gui/base/widgets/listbox.cpp b/src/gui/base/widgets/listbox.cpp
new file mode 100644
index 000000000..b97bf47d4
--- /dev/null
+++ b/src/gui/base/widgets/listbox.cpp
@@ -0,0 +1,241 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/listbox.hpp"
+
+#include "gui/base/basiccontainer.hpp"
+#include "gui/base/font.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/key.hpp"
+#include "gui/base/listmodel.hpp"
+#include "gui/base/mouseinput.hpp"
+#include "gui/base/selectionlistener.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ ListBox::ListBox() :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mSelected(-1),
+ mListModel(nullptr),
+ mWrappingEnabled(false),
+ mSelectionListeners()
+ {
+ setWidth(100);
+ setFocusable(true);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ }
+
+ ListBox::ListBox(ListModel *listModel) :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mSelected(-1),
+ mListModel(listModel),
+ mWrappingEnabled(false),
+ mSelectionListeners()
+ {
+ setWidth(100);
+ adjustSize();
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+ }
+
+ void ListBox::draw(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ListBox::logic()
+ {
+ }
+
+ int ListBox::getSelected() const
+ {
+ return mSelected;
+ }
+
+ void ListBox::setSelected(int selected)
+ {
+ if (!mListModel)
+ {
+ mSelected = -1;
+ }
+ else
+ {
+ if (selected < 0)
+ mSelected = -1;
+ else if (selected >= mListModel->getNumberOfElements())
+ mSelected = mListModel->getNumberOfElements() - 1;
+ else
+ mSelected = selected;
+ }
+
+ Rectangle scroll;
+
+ if (mSelected < 0)
+ scroll.y = 0;
+ else
+ scroll.y = getRowHeight() * mSelected;
+
+ scroll.height = getRowHeight();
+ showPart(scroll);
+
+ distributeValueChangedEvent();
+ }
+
+ void ListBox::keyPressed(KeyEvent &keyEvent A_UNUSED)
+ {
+ }
+
+ void ListBox::mousePressed(MouseEvent &mouseEvent A_UNUSED)
+ {
+ }
+
+ void ListBox::mouseWheelMovedUp(MouseEvent& mouseEvent)
+ {
+ if (isFocused())
+ {
+ if (getSelected() > 0 )
+ setSelected(getSelected() - 1);
+
+ mouseEvent.consume();
+ }
+ }
+
+ void ListBox::mouseWheelMovedDown(MouseEvent& mouseEvent)
+ {
+ if (isFocused())
+ {
+ setSelected(getSelected() + 1);
+
+ mouseEvent.consume();
+ }
+ }
+
+ void ListBox::mouseDragged(MouseEvent& mouseEvent)
+ {
+ mouseEvent.consume();
+ }
+
+ void ListBox::setListModel(ListModel *listModel)
+ {
+ mSelected = -1;
+ mListModel = listModel;
+ adjustSize();
+ }
+
+ ListModel* ListBox::getListModel()
+ {
+ return mListModel;
+ }
+
+ void ListBox::adjustSize()
+ {
+ }
+
+ bool ListBox::isWrappingEnabled() const
+ {
+ return mWrappingEnabled;
+ }
+
+ void ListBox::setWrappingEnabled(bool wrappingEnabled)
+ {
+ mWrappingEnabled = wrappingEnabled;
+ }
+
+ void ListBox::addSelectionListener(SelectionListener* selectionListener)
+ {
+ mSelectionListeners.push_back(selectionListener);
+ }
+
+ void ListBox::removeSelectionListener(SelectionListener* selectionListener)
+ {
+ mSelectionListeners.remove(selectionListener);
+ }
+
+ void ListBox::distributeValueChangedEvent()
+ {
+ for (SelectionListenerIterator iter = mSelectionListeners.begin();
+ iter != mSelectionListeners.end();
+ ++ iter)
+ {
+ SelectionEvent event(this);
+ (*iter)->valueChanged(event);
+ }
+ }
+
+ unsigned int ListBox::getRowHeight() const
+ {
+ return getFont()->getHeight();
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/listbox.hpp b/src/gui/base/widgets/listbox.hpp
new file mode 100644
index 000000000..f2780f130
--- /dev/null
+++ b/src/gui/base/widgets/listbox.hpp
@@ -0,0 +1,275 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_LISTBOX_HPP
+#define GCN_LISTBOX_HPP
+
+#include <list>
+
+#include "gui/base/keylistener.hpp"
+#include "gui/base/listmodel.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widget.hpp"
+
+namespace gcn
+{
+ class SelectionListener;
+
+ /**
+ * An implementation of a list box where an item can be selected.
+ *
+ * To be able display a list the list box uses a user provided list model.
+ * A list model can be any class that implements the ListModel interface.
+ *
+ * If an item is selected in the list box a select event will be sent to
+ * all selection listeners of the list box. If an item is selected by using
+ * a mouse click or by using the enter or space key an action event will be
+ * sent to all action listeners of the list box.
+ */
+ class ListBox :
+ public Widget,
+ public MouseListener,
+ public KeyListener
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ ListBox();
+
+ /**
+ * Constructor.
+ *
+ * @param listModel the list model to use.
+ */
+ explicit ListBox(ListModel *listModel);
+
+ A_DELETE_COPY(ListBox)
+
+ /**
+ * Destructor.
+ */
+ virtual ~ListBox()
+ { }
+
+ /**
+ * Gets the selected item as an index in the list model.
+ *
+ * @return the selected item as an index in the list model.
+ * @see setSelected
+ */
+ int getSelected() const;
+
+ /**
+ * Sets the selected item. The selected item is represented by
+ * an index from the list model.
+ *
+ * @param selected the selected item as an index from the list model.
+ * @see getSelected
+ */
+ void setSelected(int selected);
+
+ /**
+ * Sets the list model to use.
+ *
+ * @param listModel the list model to use.
+ * @see getListModel
+ */
+ void setListModel(ListModel *listModel);
+
+ /**
+ * Gets the list model used.
+ *
+ * @return the list model used.
+ * @see setListModel
+ */
+ ListModel *getListModel();
+
+ /**
+ * Adjusts the size of the list box to fit it's list model.
+ */
+ void adjustSize();
+
+ /**
+ * Checks whether the list box wraps when selecting items with a
+ * keyboard.
+ *
+ * Wrapping means that the selection of items will be wrapped. That is,
+ * if the first item is selected and up is pressed, the last item will
+ * get selected. If the last item is selected and down is pressed, the
+ * first item will get selected.
+ *
+ * @return true if wrapping is enabled, fasle otherwise.
+ * @see setWrappingEnabled
+ */
+ bool isWrappingEnabled() const;
+
+ /**
+ * Sets the list box to wrap or not when selecting items with a
+ * keyboard.
+ *
+ * Wrapping means that the selection of items will be wrapped. That is,
+ * if the first item is selected and up is pressed, the last item will
+ * get selected. If the last item is selected and down is pressed, the
+ * first item will get selected.
+ *
+ * @see isWrappingEnabled
+ */
+ void setWrappingEnabled(bool wrappingEnabled);
+
+ /**
+ * Adds a selection listener to the list box. When the selection
+ * changes an event will be sent to all selection listeners of the
+ * list box.
+ *
+ * If you delete your selection listener, be sure to also remove it
+ * using removeSelectionListener().
+ *
+ * @param selectionListener The selection listener to add.
+ * @since 0.8.0
+ */
+ void addSelectionListener(SelectionListener* selectionListener);
+
+ /**
+ * Removes a selection listener from the list box.
+ *
+ * @param selectionListener The selection listener to remove.
+ * @since 0.8.0
+ */
+ void removeSelectionListener(SelectionListener* selectionListener);
+
+ /**
+ * Gets the height of a row. Should be overridden if another row
+ * height than the font height is preferred.
+ *
+ * @return The height of a row.
+ * @since 0.8.0
+ */
+ virtual unsigned int getRowHeight() const;
+
+
+ // Inherited from Widget
+
+ virtual void draw(Graphics* graphics);
+
+ virtual void logic();
+
+
+ // Inherited from KeyListener
+
+ virtual void keyPressed(KeyEvent& keyEvent) override;
+
+
+ // Inherited from MouseListener
+
+ virtual void mousePressed(MouseEvent& mouseEvent) override;
+
+ virtual void mouseWheelMovedUp(MouseEvent& mouseEvent) override;
+
+ virtual void mouseWheelMovedDown(MouseEvent& mouseEvent) override;
+
+ virtual void mouseDragged(MouseEvent& mouseEvent) override;
+
+
+ protected:
+ /**
+ * Distributes a value changed event to all selection listeners
+ * of the list box.
+ *
+ * @since 0.8.0
+ */
+ void distributeValueChangedEvent();
+
+ /**
+ * The selected item as an index in the list model.
+ */
+ int mSelected;
+
+ /**
+ * The list model to use.
+ */
+ ListModel *mListModel;
+
+ /**
+ * True if wrapping is enabled, false otherwise.
+ */
+ bool mWrappingEnabled;
+
+ /**
+ * Typdef.
+ */
+ typedef std::list<SelectionListener*> SelectionListenerList;
+
+ /**
+ * The selection listeners of the list box.
+ */
+ SelectionListenerList mSelectionListeners;
+
+ /**
+ * Typedef.
+ */
+ typedef SelectionListenerList::iterator SelectionListenerIterator;
+ };
+} // namespace gcn
+
+#endif // end GCN_LISTBOX_HPP
diff --git a/src/gui/base/widgets/radiobutton.cpp b/src/gui/base/widgets/radiobutton.cpp
new file mode 100644
index 000000000..bfd5b1ff8
--- /dev/null
+++ b/src/gui/base/widgets/radiobutton.cpp
@@ -0,0 +1,207 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/radiobutton.hpp"
+
+#include "gui/base/font.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/key.hpp"
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ RadioButton::GroupMap RadioButton::mGroupMap;
+
+ RadioButton::RadioButton() :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mSelected(false),
+ mCaption(),
+ mGroup()
+ {
+ setSelected(false);
+
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+ }
+
+ RadioButton::RadioButton(const std::string &caption,
+ const std::string &group,
+ bool selected) :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mSelected(false),
+ mCaption(),
+ mGroup()
+ {
+ setCaption(caption);
+ setGroup(group);
+ setSelected(selected);
+
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+
+ adjustSize();
+ }
+
+ RadioButton::~RadioButton()
+ {
+ // Remove us from the group list
+ setGroup("");
+ }
+
+ bool RadioButton::isSelected() const
+ {
+ return mSelected;
+ }
+
+ void RadioButton::setSelected(bool selected)
+ {
+ if (selected && mGroup != "")
+ {
+ for (GroupIterator iter = mGroupMap.lower_bound(mGroup),
+ iterEnd = mGroupMap.upper_bound(mGroup);
+ iter != iterEnd;
+ ++ iter)
+ {
+ if (iter->second->isSelected())
+ iter->second->setSelected(false);
+ }
+ }
+
+ mSelected = selected;
+ }
+
+ const std::string &RadioButton::getCaption() const
+ {
+ return mCaption;
+ }
+
+ void RadioButton::setCaption(const std::string &caption)
+ {
+ mCaption = caption;
+ }
+
+ void RadioButton::keyPressed(KeyEvent& keyEvent A_UNUSED)
+ {
+ }
+
+ void RadioButton::mouseClicked(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.getButton() == MouseEvent::LEFT)
+ {
+ setSelected(true);
+ distributeActionEvent();
+ }
+ }
+
+ void RadioButton::mouseDragged(MouseEvent& mouseEvent)
+ {
+ mouseEvent.consume();
+ }
+
+ void RadioButton::setGroup(const std::string &group)
+ {
+ if (mGroup != "")
+ {
+ for (GroupIterator iter = mGroupMap.lower_bound(mGroup),
+ iterEnd = mGroupMap.upper_bound(mGroup);
+ iter != iterEnd;
+ ++ iter)
+ {
+ if (iter->second == this)
+ {
+ mGroupMap.erase(iter);
+ break;
+ }
+ }
+ }
+
+ if (group != "")
+ {
+ mGroupMap.insert(
+ std::pair<std::string, RadioButton *>(group, this));
+ }
+
+ mGroup = group;
+ }
+
+ const std::string &RadioButton::getGroup() const
+ {
+ return mGroup;
+ }
+
+ void RadioButton::adjustSize()
+ {
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/radiobutton.hpp b/src/gui/base/widgets/radiobutton.hpp
new file mode 100644
index 000000000..07e3d656a
--- /dev/null
+++ b/src/gui/base/widgets/radiobutton.hpp
@@ -0,0 +1,226 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_RADIOBUTTON_HPP
+#define GCN_RADIOBUTTON_HPP
+
+#include <map>
+#include <string>
+
+#include "gui/base/keylistener.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widget.hpp"
+
+namespace gcn
+{
+ /**
+ * An implementation of a radio button where a user can select or deselect
+ * the radio button and where the status of the radio button is displayed to the user.
+ * A radio button can belong to a group and when a radio button belongs to a
+ * group only one radio button can be selected in the group. A radio button is
+ * capable of displaying a caption.
+ *
+ * If a radio button's state changes an action event will be sent to all action
+ * listeners of the check box.
+ */
+ class RadioButton :
+ public Widget,
+ public MouseListener,
+ public KeyListener
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ RadioButton();
+
+ /**
+ * Constructor. The radio button will be automatically resized
+ * to fit the caption.
+ *
+ * @param caption The caption of the radio button.
+ * @param group The group the radio button should belong to.
+ * @param selected True if the radio button should be selected.
+ */
+ RadioButton(const std::string &caption,
+ const std::string &group,
+ bool selected = false);
+
+ A_DELETE_COPY(RadioButton)
+
+ /**
+ * Destructor.
+ */
+ virtual ~RadioButton();
+
+ /**
+ * Checks if the radio button is selected.
+ *
+ * @return True if the radio button is selecte, false otherwise.
+ * @see setSelected
+ */
+ bool isSelected() const;
+
+ /**
+ * Sets the radio button to selected or not.
+ *
+ * @param selected True if the radio button should be selected,
+ * false otherwise.
+ * @see isSelected
+ */
+ void setSelected(bool selected);
+
+ /**
+ * Gets the caption of the radio button.
+ *
+ * @return The caption of the radio button.
+ * @see setCaption
+ */
+ const std::string &getCaption() const;
+
+ /**
+ * Sets the caption of the radio button. It's advisable to call
+ * adjustSize after setting of the caption to adjust the
+ * radio button's size to fit the caption.
+ *
+ * @param caption The caption of the radio button.
+ * @see getCaption, adjustSize
+ */
+ void setCaption(const std::string &caption);
+
+ /**
+ * Sets the group the radio button should belong to. Note that
+ * a radio button group is unique per application, not per Gui object
+ * as the group is stored in a static map.
+ *
+ * @param group The name of the group.
+ * @see getGroup
+ */
+ void setGroup(const std::string &group);
+
+ /**
+ * Gets the group the radio button belongs to.
+ *
+ * @return The group the radio button belongs to.
+ * @see setGroup
+ */
+ const std::string &getGroup() const;
+
+ /**
+ * Adjusts the radio button's size to fit the caption.
+ */
+ void adjustSize();
+
+
+ // Inherited from KeyListener
+
+ virtual void keyPressed(KeyEvent& keyEvent) override;
+
+
+ // Inherited from MouseListener
+
+ virtual void mouseClicked(MouseEvent& mouseEvent) override;
+
+ virtual void mouseDragged(MouseEvent& mouseEvent) override;
+
+ protected:
+ /**
+ * Draws the box.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawBox(Graphics *graphics) = 0;
+
+ /**
+ * True if the radio button is selected, false otherwise.
+ */
+ bool mSelected;
+
+ /**
+ * Holds the caption of the radio button.
+ */
+ std::string mCaption;
+
+ /**
+ * Holds the group of the radio button.
+ */
+ std::string mGroup;
+
+ /**
+ * Typdef.
+ */
+ typedef std::multimap<std::string, RadioButton *> GroupMap;
+
+ /**
+ * Typdef.
+ */
+ typedef GroupMap::iterator GroupIterator;
+
+ /**
+ * Holds all available radio button groups.
+ */
+ static GroupMap mGroupMap;
+ };
+} // namespace gcn
+
+#endif // end GCN_RADIOBUTTON_HPP
diff --git a/src/gui/base/widgets/scrollarea.cpp b/src/gui/base/widgets/scrollarea.cpp
new file mode 100644
index 000000000..e3dcfc61c
--- /dev/null
+++ b/src/gui/base/widgets/scrollarea.cpp
@@ -0,0 +1,600 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/scrollarea.hpp"
+
+#include "gui/base/exception.hpp"
+#include "gui/base/graphics.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ ScrollArea::ScrollArea() :
+ gcn::BasicContainer(),
+ gcn::MouseListener(),
+ mVScroll(0),
+ mHScroll(0),
+ mScrollbarWidth(12),
+ mHPolicy(SHOW_AUTO),
+ mVPolicy(SHOW_AUTO),
+ mVBarVisible(false),
+ mHBarVisible(false),
+ mUpButtonPressed(false),
+ mDownButtonPressed(false),
+ mLeftButtonPressed(false),
+ mRightButtonPressed(false),
+ mUpButtonScrollAmount(10),
+ mDownButtonScrollAmount(10),
+ mLeftButtonScrollAmount(10),
+ mRightButtonScrollAmount(10),
+ mIsVerticalMarkerDragged(false),
+ mIsHorizontalMarkerDragged(false),
+ mHorizontalMarkerDragOffset(0),
+ mVerticalMarkerDragOffset(0),
+ mOpaque(true)
+ {
+ addMouseListener(this);
+ }
+
+ ScrollArea::ScrollArea(Widget *const content) :
+ gcn::BasicContainer(),
+ gcn::MouseListener(),
+ mVScroll(0),
+ mHScroll(0),
+ mScrollbarWidth(12),
+ mHPolicy(SHOW_AUTO),
+ mVPolicy(SHOW_AUTO),
+ mVBarVisible(false),
+ mHBarVisible(false),
+ mUpButtonPressed(false),
+ mDownButtonPressed(false),
+ mLeftButtonPressed(false),
+ mRightButtonPressed(false),
+ mUpButtonScrollAmount(10),
+ mDownButtonScrollAmount(10),
+ mLeftButtonScrollAmount(10),
+ mRightButtonScrollAmount(10),
+ mIsVerticalMarkerDragged(false),
+ mIsHorizontalMarkerDragged(false),
+ mHorizontalMarkerDragOffset(0),
+ mVerticalMarkerDragOffset(0),
+ mOpaque(true)
+ {
+ setContent(content);
+ addMouseListener(this);
+ }
+
+ ScrollArea::ScrollArea(Widget *content,
+ ScrollPolicy hPolicy,
+ ScrollPolicy vPolicy) :
+ gcn::BasicContainer(),
+ gcn::MouseListener(),
+ mVScroll(0),
+ mHScroll(0),
+ mScrollbarWidth(12),
+ mHPolicy(hPolicy),
+ mVPolicy(vPolicy),
+ mVBarVisible(false),
+ mHBarVisible(false),
+ mUpButtonPressed(false),
+ mDownButtonPressed(false),
+ mLeftButtonPressed(false),
+ mRightButtonPressed(false),
+ mUpButtonScrollAmount(10),
+ mDownButtonScrollAmount(10),
+ mLeftButtonScrollAmount(10),
+ mRightButtonScrollAmount(10),
+ mIsVerticalMarkerDragged(false),
+ mIsHorizontalMarkerDragged(false),
+ mHorizontalMarkerDragOffset(0),
+ mVerticalMarkerDragOffset(0),
+ mOpaque(true)
+ {
+ setContent(content);
+ addMouseListener(this);
+ }
+
+ ScrollArea::~ScrollArea()
+ {
+ setContent(nullptr);
+ }
+
+ void ScrollArea::setContent(Widget* widget)
+ {
+ if (widget)
+ {
+ clear();
+ add(widget);
+ widget->setPosition(0, 0);
+ }
+ else
+ {
+ clear();
+ }
+
+ checkPolicies();
+ }
+
+ Widget* ScrollArea::getContent()
+ {
+ if (!mWidgets.empty())
+ return *mWidgets.begin();
+
+ return nullptr;
+ }
+
+ void ScrollArea::setHorizontalScrollPolicy(ScrollPolicy hPolicy)
+ {
+ mHPolicy = hPolicy;
+ checkPolicies();
+ }
+
+ ScrollArea::ScrollPolicy ScrollArea::getHorizontalScrollPolicy() const
+ {
+ return mHPolicy;
+ }
+
+ void ScrollArea::setVerticalScrollPolicy(ScrollPolicy vPolicy)
+ {
+ mVPolicy = vPolicy;
+ checkPolicies();
+ }
+
+ ScrollArea::ScrollPolicy ScrollArea::getVerticalScrollPolicy() const
+ {
+ return mVPolicy;
+ }
+
+ void ScrollArea::setScrollPolicy(ScrollPolicy hPolicy,
+ ScrollPolicy vPolicy)
+ {
+ mHPolicy = hPolicy;
+ mVPolicy = vPolicy;
+ checkPolicies();
+ }
+
+ void ScrollArea::setVerticalScrollAmount(int vScroll)
+ {
+ const int max = getVerticalMaxScroll();
+
+ mVScroll = vScroll;
+
+ if (vScroll > max)
+ mVScroll = max;
+
+ if (vScroll < 0)
+ mVScroll = 0;
+ }
+
+ int ScrollArea::getVerticalScrollAmount() const
+ {
+ return mVScroll;
+ }
+
+ void ScrollArea::setHorizontalScrollAmount(int hScroll)
+ {
+ const int max = getHorizontalMaxScroll();
+
+ mHScroll = hScroll;
+
+ if (hScroll > max)
+ mHScroll = max;
+ else if (hScroll < 0)
+ mHScroll = 0;
+ }
+
+ int ScrollArea::getHorizontalScrollAmount() const
+ {
+ return mHScroll;
+ }
+
+ void ScrollArea::setScrollAmount(int hScroll, int vScroll)
+ {
+ setHorizontalScrollAmount(hScroll);
+ setVerticalScrollAmount(vScroll);
+ }
+
+ int ScrollArea::getHorizontalMaxScroll()
+ {
+ checkPolicies();
+
+ const Widget *const content = getContent();
+ if (!content)
+ return 0;
+
+ const int value = content->getWidth() - getChildrenArea().width +
+ 2 * content->getFrameSize();
+
+ if (value < 0)
+ return 0;
+
+ return value;
+ }
+
+ int ScrollArea::getVerticalMaxScroll()
+ {
+ checkPolicies();
+
+ const Widget *const content = getContent();
+ if (!content)
+ return 0;
+
+ int value;
+
+ value = content->getHeight() - getChildrenArea().height +
+ 2 * content->getFrameSize();
+
+ if (value < 0)
+ return 0;
+
+ return value;
+ }
+
+ void ScrollArea::setScrollbarWidth(int width)
+ {
+ if (width > 0)
+ mScrollbarWidth = width;
+ else
+ throw GCN_EXCEPTION("Width should be greater then 0.");
+ }
+
+ int ScrollArea::getScrollbarWidth() const
+ {
+ return mScrollbarWidth;
+ }
+
+ void ScrollArea::mouseReleased(MouseEvent& mouseEvent)
+ {
+ mUpButtonPressed = false;
+ mDownButtonPressed = false;
+ mLeftButtonPressed = false;
+ mRightButtonPressed = false;
+ mIsHorizontalMarkerDragged = false;
+ mIsVerticalMarkerDragged = false;
+
+ mouseEvent.consume();
+ }
+
+ void ScrollArea::draw(Graphics *graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawHBar(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawVBar(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawBackground(Graphics *graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawUpButton(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawDownButton(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawLeftButton(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawRightButton(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawVMarker(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::drawHMarker(Graphics* graphics A_UNUSED)
+ {
+ }
+
+ void ScrollArea::logic()
+ {
+ BLOCK_START("ScrollArea::logic")
+ checkPolicies();
+
+ setVerticalScrollAmount(getVerticalScrollAmount());
+ setHorizontalScrollAmount(getHorizontalScrollAmount());
+
+ Widget *const content = getContent();
+ if (content)
+ {
+ const int frameSize = content->getFrameSize();
+ content->setPosition(-mHScroll + frameSize, -mVScroll + frameSize);
+ content->logic();
+ }
+ BLOCK_END("ScrollArea::logic")
+ }
+
+ void ScrollArea::checkPolicies()
+ {
+ const int w = getWidth();
+ const int h = getHeight();
+
+ mHBarVisible = false;
+ mVBarVisible = false;
+
+ const Widget *const content = getContent();
+ if (!content)
+ {
+ mHBarVisible = (mHPolicy == SHOW_ALWAYS);
+ mVBarVisible = (mVPolicy == SHOW_ALWAYS);
+ return;
+ }
+
+ if (mHPolicy == SHOW_AUTO &&
+ mVPolicy == SHOW_AUTO)
+ {
+ if (content->getWidth() <= w
+ && content->getHeight() <= h)
+ {
+ mHBarVisible = false;
+ mVBarVisible = false;
+ }
+
+ if (content->getWidth() > w)
+ {
+ mHBarVisible = true;
+ }
+
+ if ((content->getHeight() > h)
+ || (mHBarVisible && content->getHeight()
+ > h - mScrollbarWidth))
+ {
+ mVBarVisible = true;
+ }
+
+ if (mVBarVisible && content->getWidth() > w - mScrollbarWidth)
+ mHBarVisible = true;
+
+ return;
+ }
+
+ switch (mHPolicy)
+ {
+ case SHOW_NEVER:
+ mHBarVisible = false;
+ break;
+
+ case SHOW_ALWAYS:
+ mHBarVisible = true;
+ break;
+
+ case SHOW_AUTO:
+ if (mVPolicy == SHOW_NEVER)
+ {
+ mHBarVisible = (content->getWidth() > w);
+ }
+ else // (mVPolicy == SHOW_ALWAYS)
+ {
+ mHBarVisible = (content->getWidth()
+ > w - mScrollbarWidth);
+ }
+ break;
+
+ default:
+ throw GCN_EXCEPTION("Horizontal scroll policy invalid.");
+ }
+
+ switch (mVPolicy)
+ {
+ case SHOW_NEVER:
+ mVBarVisible = false;
+ break;
+
+ case SHOW_ALWAYS:
+ mVBarVisible = true;
+ break;
+
+ case SHOW_AUTO:
+ if (mHPolicy == SHOW_NEVER)
+ {
+ mVBarVisible = (content->getHeight() > h);
+ }
+ else // (mHPolicy == SHOW_ALWAYS)
+ {
+ mVBarVisible = (content->getHeight()
+ > h - mScrollbarWidth);
+ }
+ break;
+ default:
+ throw GCN_EXCEPTION("Vertical scroll policy invalid.");
+ }
+ }
+
+ Rectangle ScrollArea::getChildrenArea()
+ {
+ const Rectangle area = Rectangle(0, 0,
+ mVBarVisible ? (getWidth() - mScrollbarWidth) : getWidth(),
+ mHBarVisible ? (getHeight() - mScrollbarWidth) : getHeight());
+
+ if (area.width < 0 || area.height < 0)
+ return Rectangle();
+
+ return area;
+ }
+
+ void ScrollArea::showWidgetPart(Widget* widget, Rectangle area)
+ {
+ const Widget *const content = getContent();
+ if (widget != content)
+ throw GCN_EXCEPTION("Widget not content widget");
+
+ BasicContainer::showWidgetPart(widget, area);
+
+ setHorizontalScrollAmount(content->getFrameSize()
+ - content->getX());
+ setVerticalScrollAmount(content->getFrameSize()
+ - content->getY());
+ }
+
+ Widget *ScrollArea::getWidgetAt(int x, int y)
+ {
+ if (getChildrenArea().isPointInRect(x, y))
+ return getContent();
+
+ return nullptr;
+ }
+
+ void ScrollArea::mouseWheelMovedUp(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.isConsumed())
+ return;
+
+ setVerticalScrollAmount(getVerticalScrollAmount()
+ - getChildrenArea().height / 8);
+
+ mouseEvent.consume();
+ }
+
+ void ScrollArea::mouseWheelMovedDown(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.isConsumed())
+ return;
+
+ setVerticalScrollAmount(getVerticalScrollAmount()
+ + getChildrenArea().height / 8);
+
+ mouseEvent.consume();
+ }
+
+ void ScrollArea::setWidth(int width)
+ {
+ Widget::setWidth(width);
+ checkPolicies();
+ }
+
+ void ScrollArea::setHeight(int height)
+ {
+ Widget::setHeight(height);
+ checkPolicies();
+ }
+
+ void ScrollArea::setDimension(const Rectangle& dimension)
+ {
+ Widget::setDimension(dimension);
+ checkPolicies();
+ }
+
+ void ScrollArea::setLeftButtonScrollAmount(int amount)
+ {
+ mLeftButtonScrollAmount = amount;
+ }
+
+ void ScrollArea::setRightButtonScrollAmount(int amount)
+ {
+ mRightButtonScrollAmount = amount;
+ }
+
+ void ScrollArea::setUpButtonScrollAmount(int amount)
+ {
+ mUpButtonScrollAmount = amount;
+ }
+
+ void ScrollArea::setDownButtonScrollAmount(int amount)
+ {
+ mDownButtonScrollAmount = amount;
+ }
+
+ int ScrollArea::getLeftButtonScrollAmount() const
+ {
+ return mLeftButtonScrollAmount;
+ }
+
+ int ScrollArea::getRightButtonScrollAmount() const
+ {
+ return mRightButtonScrollAmount;
+ }
+
+ int ScrollArea::getUpButtonScrollAmount() const
+ {
+ return mUpButtonScrollAmount;
+ }
+
+ int ScrollArea::getDownButtonScrollAmount() const
+ {
+ return mDownButtonScrollAmount;
+ }
+
+ void ScrollArea::setOpaque(bool opaque)
+ {
+ mOpaque = opaque;
+ }
+
+ bool ScrollArea::isOpaque() const
+ {
+ return mOpaque;
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/scrollarea.hpp b/src/gui/base/widgets/scrollarea.hpp
new file mode 100644
index 000000000..e75390ec0
--- /dev/null
+++ b/src/gui/base/widgets/scrollarea.hpp
@@ -0,0 +1,549 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_SCROLLAREA_HPP
+#define GCN_SCROLLAREA_HPP
+
+#include <string>
+
+#include "gui/base/basiccontainer.hpp"
+#include "gui/base/mouselistener.hpp"
+
+namespace gcn
+{
+ /**
+ * Implementation if a scrollable area used to view widgets larger than the scroll area.
+ * A scroll area can be customized to always show scroll bars or to show them only when
+ * necessary.
+ */
+ class ScrollArea:
+ public BasicContainer,
+ public MouseListener
+ {
+ public:
+ /**
+ * Scrollpolicies for the horizontal and vertical scrollbar.
+ * The policies are:
+ *
+ * SHOW_ALWAYS - Always show the scrollbars no matter what.
+ * SHOW_NEVER - Never show the scrollbars no matter waht.
+ * SHOW_AUTO - Show the scrollbars only when needed. That is if the
+ * content grows larger then the ScrollArea.
+ */
+ enum ScrollPolicy
+ {
+ SHOW_ALWAYS = 0,
+ SHOW_NEVER,
+ SHOW_AUTO
+ };
+
+ /**
+ * Constructor.
+ */
+ ScrollArea();
+
+ /**
+ * Constructor.
+ *
+ * @param content The content of the scroll area.
+ */
+ explicit ScrollArea(Widget *const content);
+
+ /**
+ * Constructor.
+ *
+ * @param content The content of the scroll area.
+ * @param hPolicy The policy for the horizontal scrollbar. See enum with
+ * policies.
+ * @param vPolicy The policy for the vertical scrollbar. See enum with
+ * policies.
+ */
+ ScrollArea(Widget *content,
+ ScrollPolicy hPolicy,
+ ScrollPolicy vPolicy);
+
+ A_DELETE_COPY(ScrollArea)
+
+ /**
+ * Destructor.
+ */
+ virtual ~ScrollArea();
+
+ /**
+ * Sets the content.
+ *
+ * @param widget The content of the scroll area.
+ */
+ void setContent(Widget* widget);
+
+ /**
+ * Gets the content.
+ *
+ * @return The content of the scroll area.
+ */
+ Widget* getContent();
+
+ /**
+ * Sets the horizontal scrollbar policy. See enum with policies.
+ *
+ * @param hPolicy The policy for the horizontal scrollbar.
+ * @see getHorizontalScrollPolicy
+ */
+ void setHorizontalScrollPolicy(ScrollPolicy hPolicy);
+
+ /**
+ * Gets the horizontal scrollbar policy. See enum with policies.
+ *
+ * @return The policy for the horizontal scrollbar policy.
+ * @see setHorizontalScrollPolicy, setScrollPolicy
+ */
+ ScrollPolicy getHorizontalScrollPolicy() const;
+
+ /**
+ * Sets the vertical scrollbar policy. See enum with policies.
+ *
+ * @param vPolicy The policy for the vertical scrollbar.
+ * @see getVerticalScrollPolicy
+ */
+ void setVerticalScrollPolicy(ScrollPolicy vPolicy);
+
+ /**
+ * Gets the vertical scrollbar policy. See enum with policies.
+ *
+ * @return The policy for the vertical scrollbar.
+ * @see setVerticalScrollPolicy, setScrollPolicy
+ */
+ ScrollPolicy getVerticalScrollPolicy() const;
+
+ /**
+ * Sets the horizontal and vertical scrollbar policy.
+ *
+ * @param hPolicy The policy for the horizontal scrollbar.
+ * @param vPolicy The policy for the vertical scrollbar.
+ * @see getVerticalScrollPolicy, getHorizontalScrollPolicy
+ */
+ void setScrollPolicy(ScrollPolicy hPolicy, ScrollPolicy vPolicy);
+
+ /**
+ * Sets the amount to scroll vertically.
+ *
+ * @param vScroll The amount to scroll.
+ * @see getVerticalScrollAmount
+ */
+ void setVerticalScrollAmount(int vScroll);
+
+ /**
+ * Gets the amount that is scrolled vertically.
+ *
+ * @return The scroll amount on vertical scroll.
+ * @see setVerticalScrollAmount, setScrollAmount
+ */
+ int getVerticalScrollAmount() const;
+
+ /**
+ * Sets the amount to scroll horizontally.
+ *
+ * @param hScroll The amount to scroll.
+ * @see getHorizontalScrollAmount
+ */
+ void setHorizontalScrollAmount(int hScroll);
+
+ /**
+ * Gets the amount that is scrolled horizontally.
+ *
+ * @return The scroll amount on horizontal scroll.
+ * @see setHorizontalScrollAmount, setScrollAmount
+ */
+ int getHorizontalScrollAmount() const;
+
+ /**
+ * Sets the amount to scroll horizontally and vertically.
+ *
+ * @param hScroll The amount to scroll on horizontal scroll.
+ * @param vScroll The amount to scroll on vertical scroll.
+ * @see getHorizontalScrollAmount, getVerticalScrollAmount
+ */
+ void setScrollAmount(int hScroll, int vScroll);
+
+ /**
+ * Gets the maximum amount of horizontal scroll.
+ *
+ * @return The horizontal max scroll.
+ */
+ int getHorizontalMaxScroll();
+
+ /**
+ * Gets the maximum amount of vertical scroll.
+ *
+ * @return The vertical max scroll.
+ */
+ int getVerticalMaxScroll();
+
+ /**
+ * Sets the width of the scroll bars.
+ *
+ * @param width The width of the scroll bars.
+ * @see getScrollbarWidth
+ */
+ void setScrollbarWidth(int width);
+
+ /**
+ * Gets the width of the scroll bars.
+ *
+ * @return the width of the ScrollBar.
+ * @see setScrollbarWidth
+ */
+ int getScrollbarWidth() const;
+
+ /**
+ * Sets the amount to scroll in pixels when the left scroll button is
+ * pushed.
+ *
+ * @param amount The amount to scroll in pixels.
+ * @see getLeftButtonScrollAmount
+ */
+ void setLeftButtonScrollAmount(int amount);
+
+ /**
+ * Sets the amount to scroll in pixels when the right scroll button is
+ * pushed.
+ *
+ * @param amount The amount to scroll in pixels.
+ * @see getRightButtonScrollAmount
+ */
+ void setRightButtonScrollAmount(int amount);
+
+ /**
+ * Sets the amount to scroll in pixels when the up scroll button is
+ * pushed.
+ *
+ * @param amount The amount to scroll in pixels.
+ * @see getUpButtonScrollAmount
+ */
+ void setUpButtonScrollAmount(int amount);
+
+ /**
+ * Sets the amount to scroll in pixels when the down scroll button is
+ * pushed.
+ *
+ * @param amount The amount to scroll in pixels.
+ * @see getDownButtonScrollAmount
+ */
+ void setDownButtonScrollAmount(int amount);
+
+ /**
+ * Gets the amount to scroll in pixels when the left scroll button is
+ * pushed.
+ *
+ * @return The amount to scroll in pixels.
+ * @see setLeftButtonScrollAmount
+ */
+ int getLeftButtonScrollAmount() const;
+
+ /**
+ * Gets the amount to scroll in pixels when the right scroll button is
+ * pushed.
+ *
+ * @return The amount to scroll in pixels.
+ * @see setRightButtonScrollAmount
+ */
+ int getRightButtonScrollAmount() const;
+
+ /**
+ * Gets the amount to scroll in pixels when the up scroll button is
+ * pushed.
+ *
+ * @return The amount to scroll in pixels.
+ * @see setUpButtonScrollAmount
+ */
+ int getUpButtonScrollAmount() const;
+
+ /**
+ * Gets the amount to scroll in pixels when the down scroll button is
+ * pushed.
+ *
+ * @return The amount to scroll in pixels.
+ * @see setDownButtonScrollAmount
+ */
+ int getDownButtonScrollAmount() const;
+
+ /**
+ * Sets the scroll area to be opaque, that is sets the scoll area
+ * to display its background.
+ *
+ * @param opaque True if the scoll area should be opaque, false otherwise.
+ */
+ void setOpaque(bool opaque);
+
+ /**
+ * Checks if the scroll area is opaque, that is if the scroll area
+ * displays its background.
+ *
+ * @return True if the scroll area is opaque, false otherwise.
+ */
+ bool isOpaque() const;
+
+ // Inherited from BasicContainer
+
+ virtual void showWidgetPart(Widget* widget, Rectangle area);
+
+ virtual Rectangle getChildrenArea();
+
+ virtual Widget *getWidgetAt(int x, int y);
+
+
+ // Inherited from Widget
+
+ virtual void draw(Graphics *graphics);
+
+ virtual void logic();
+
+ void setWidth(int width);
+
+ void setHeight(int height);
+
+ void setDimension(const Rectangle& dimension);
+
+
+ // Inherited from MouseListener
+
+ virtual void mouseReleased(MouseEvent& mouseEvent) override;
+
+ virtual void mouseWheelMovedUp(MouseEvent& mouseEvent) override;
+
+ virtual void mouseWheelMovedDown(MouseEvent& mouseEvent) override;
+
+ protected:
+ /**
+ * Draws the background of the scroll area, that is
+ * the area behind the content.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawBackground(Graphics *graphics);
+
+ /**
+ * Draws the up button.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawUpButton(Graphics *graphics);
+
+ /**
+ * Draws the down button.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawDownButton(Graphics *graphics);
+
+ /**
+ * Draws the left button.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawLeftButton(Graphics *graphics);
+
+ /**
+ * Draws the right button.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawRightButton(Graphics *graphics);
+
+ /**
+ * Draws the vertical scroll bar.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawVBar(Graphics* graphics);
+
+ /**
+ * Draws the horizontal scroll bar.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawHBar(Graphics* graphics);
+
+ /**
+ * Draws the vertical marker.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawVMarker(Graphics* graphics);
+
+ /**
+ * Draws the horizontal marker.
+ *
+ * @param graphics a Graphics object to draw with.
+ */
+ virtual void drawHMarker(Graphics* graphics);
+
+ /**
+ * Checks the policies for the scroll bars.
+ */
+ virtual void checkPolicies();
+
+ /**
+ * Holds the vertical scroll amount.
+ */
+ int mVScroll;
+
+ /**
+ * Holds the horizontal scroll amount.
+ */
+ int mHScroll;
+
+ /**
+ * Holds the width of the scroll bars.
+ */
+ int mScrollbarWidth;
+
+ /**
+ * Holds the horizontal scroll bar policy.
+ */
+ ScrollPolicy mHPolicy;
+
+ /**
+ * Holds the vertical scroll bar policy.
+ */
+ ScrollPolicy mVPolicy;
+
+ /**
+ * True if the vertical scroll bar is visible, false otherwise.
+ */
+ bool mVBarVisible;
+
+ /**
+ * True if the horizontal scroll bar is visible, false otherwise.
+ */
+ bool mHBarVisible;
+
+ /**
+ * True if the up button is pressed, false otherwise.
+ */
+ bool mUpButtonPressed;
+
+ /**
+ * True if the down button is pressed, false otherwise.
+ */
+ bool mDownButtonPressed;
+
+ /**
+ * True if the left button is pressed, false otherwise.
+ */
+ bool mLeftButtonPressed;
+
+ /**
+ * True if the right button is pressed, false otherwise.
+ */
+ bool mRightButtonPressed;
+
+ /**
+ * Holds the up button scroll amount.
+ */
+ int mUpButtonScrollAmount;
+
+ /**
+ * Holds the down button scroll amount.
+ */
+ int mDownButtonScrollAmount;
+
+ /**
+ * Holds the left button scroll amount.
+ */
+ int mLeftButtonScrollAmount;
+
+ /**
+ * Holds the right button scroll amount.
+ */
+ int mRightButtonScrollAmount;
+
+ /**
+ * True if the vertical marked is dragged.
+ */
+ bool mIsVerticalMarkerDragged;
+
+ /**
+ * True if the horizontal marked is dragged.
+ */
+ bool mIsHorizontalMarkerDragged;
+
+ /**
+ * Holds the horizontal markers drag offset.
+ */
+ int mHorizontalMarkerDragOffset;
+
+ /**
+ * Holds the vertical markers drag offset.
+ */
+ int mVerticalMarkerDragOffset;
+
+ /**
+ * True if the scroll area should be opaque (that is
+ * display its background), false otherwise.
+ */
+ bool mOpaque;
+ };
+} // namespace gcn
+
+#endif // end GCN_SCROLLAREA_HPP
diff --git a/src/gui/base/widgets/slider.cpp b/src/gui/base/widgets/slider.cpp
new file mode 100644
index 000000000..a1a106303
--- /dev/null
+++ b/src/gui/base/widgets/slider.cpp
@@ -0,0 +1,231 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/slider.hpp"
+
+#include "gui/base/graphics.hpp"
+#include "gui/base/key.hpp"
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Slider::Slider(const double scaleEnd) :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mDragged(false),
+ mValue(0),
+ mStepLength(scaleEnd / 10),
+ mMarkerLength(10),
+ mScaleStart(0),
+ mScaleEnd(scaleEnd),
+ mOrientation(HORIZONTAL)
+ {
+ setFocusable(true);
+ setFrameSize(1);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ }
+
+ Slider::Slider(const double scaleStart, const double scaleEnd) :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mDragged(false),
+ mValue(scaleStart),
+ mStepLength((scaleEnd - scaleStart) / 10),
+ mMarkerLength(10),
+ mScaleStart(scaleStart),
+ mScaleEnd(scaleEnd),
+ mOrientation(HORIZONTAL)
+ {
+ setFocusable(true);
+ setFrameSize(1);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ }
+
+ void Slider::setScale(double scaleStart, double scaleEnd)
+ {
+ mScaleStart = scaleStart;
+ mScaleEnd = scaleEnd;
+ }
+
+ double Slider::getScaleStart() const
+ {
+ return mScaleStart;
+ }
+
+ void Slider::setScaleStart(double scaleStart)
+ {
+ mScaleStart = scaleStart;
+ }
+
+ double Slider::getScaleEnd() const
+ {
+ return mScaleEnd;
+ }
+
+ void Slider::setScaleEnd(double scaleEnd)
+ {
+ mScaleEnd = scaleEnd;
+ }
+
+ void Slider::setValue(double value)
+ {
+ if (value > getScaleEnd())
+ {
+ mValue = getScaleEnd();
+ return;
+ }
+
+ if (value < getScaleStart())
+ {
+ mValue = getScaleStart();
+ return;
+ }
+
+ mValue = value;
+ }
+
+ double Slider::getValue() const
+ {
+ return mValue;
+ }
+
+ int Slider::getMarkerLength() const
+ {
+ return mMarkerLength;
+ }
+
+ void Slider::setMarkerLength(int length)
+ {
+ mMarkerLength = length;
+ }
+
+ void Slider::setOrientation(Slider::Orientation orientation)
+ {
+ mOrientation = orientation;
+ }
+
+ Slider::Orientation Slider::getOrientation() const
+ {
+ return mOrientation;
+ }
+
+ double Slider::markerPositionToValue(int v) const
+ {
+ int w;
+ if (getOrientation() == HORIZONTAL)
+ w = getWidth();
+ else
+ w = getHeight();
+
+ const double pos = v / (static_cast<double>(w) - getMarkerLength());
+ return (1.0 - pos) * getScaleStart() + pos * getScaleEnd();
+ }
+
+ int Slider::valueToMarkerPosition(double value) const
+ {
+ int v;
+ if (getOrientation() == HORIZONTAL)
+ v = getWidth();
+ else
+ v = getHeight();
+
+ const int w = static_cast<int>((v - getMarkerLength())
+ * (value - getScaleStart())
+ / (getScaleEnd() - getScaleStart()));
+
+ if (w < 0)
+ return 0;
+
+ if (w > v - getMarkerLength())
+ return v - getMarkerLength();
+
+ return w;
+ }
+
+ void Slider::setStepLength(double length)
+ {
+ mStepLength = length;
+ }
+
+ double Slider::getStepLength() const
+ {
+ return mStepLength;
+ }
+
+ int Slider::getMarkerPosition() const
+ {
+ return valueToMarkerPosition(getValue());
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/slider.hpp b/src/gui/base/widgets/slider.hpp
new file mode 100644
index 000000000..32cdfefb9
--- /dev/null
+++ b/src/gui/base/widgets/slider.hpp
@@ -0,0 +1,293 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_SLIDER_HPP
+#define GCN_SLIDER_HPP
+
+#include "gui/base/keylistener.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widget.hpp"
+
+namespace gcn
+{
+ /**
+ * An implementation of a slider where a user can select different values by
+ * sliding between a start value and an end value of a scale.
+ *
+ * If the selected value is changed an action event will be sent to all
+ * action listeners of the slider.
+ */
+ class Slider :
+ public Widget,
+ public MouseListener,
+ public KeyListener
+ {
+ public:
+ /**
+ * Draw orientations for the slider. A slider can be drawn vertically or
+ * horizontally.
+ */
+ enum Orientation
+ {
+ HORIZONTAL = 0,
+ VERTICAL
+ };
+
+ /**
+ * Constructor. The default start value of the slider scale is zero.
+ *
+ * @param scaleEnd The end value of the slider scale.
+ */
+ explicit Slider(const double scaleEnd = 1.0);
+
+ /**
+ * Constructor.
+ *
+ * @param scaleStart The start value of the slider scale.
+ * @param scaleEnd The end value of the slider scale.
+ */
+ Slider(const double scaleStart, const double scaleEnd);
+
+ A_DELETE_COPY(Slider)
+
+ /**
+ * Destructor.
+ */
+ virtual ~Slider()
+ { }
+
+ /**
+ * Sets the scale of the slider.
+ *
+ * @param scaleStart The start value of the scale.
+ * @param scaleEnd tThe end of value the scale.
+ * @see getScaleStart, getScaleEnd
+ */
+ void setScale(double scaleStart, double scaleEnd);
+
+ /**
+ * Gets the start value of the scale.
+ *
+ * @return The start value of the scale.
+ * @see setScaleStart, setScale
+ */
+ double getScaleStart() const;
+
+ /**
+ * Sets the start value of the scale.
+ *
+ * @param scaleStart The start value of the scale.
+ * @see getScaleStart
+ */
+ void setScaleStart(double scaleStart);
+
+ /**
+ * Gets the end value of the scale.
+ *
+ * @return The end value of the scale.
+ * @see setScaleEnd, setScale
+ */
+ double getScaleEnd() const;
+
+ /**
+ * Sets the end value of the scale.
+ *
+ * @param scaleEnd The end value of the scale.
+ * @see getScaleEnd
+ */
+ void setScaleEnd(double scaleEnd);
+
+ /**
+ * Gets the current selected value.
+ *
+ * @return The current selected value.
+ * @see setValue
+ */
+ double getValue() const;
+
+ /**
+ * Sets the current selected value.
+ *
+ * @param value The current selected value.
+ * @see getValue
+ */
+ void setValue(double value);
+
+ /**
+ * Sets the length of the marker.
+ *
+ * @param length The length for the marker.
+ * @see getMarkerLength
+ */
+ void setMarkerLength(int length);
+
+ /**
+ * Gets the length of the marker.
+ *
+ * @return The length of the marker.
+ * @see setMarkerLength
+ */
+ int getMarkerLength() const;
+
+ /**
+ * Sets the orientation of the slider. A slider can be drawn vertically
+ * or horizontally.
+ *
+ * @param orientation The orientation of the slider.
+ * @see getOrientation
+ */
+ void setOrientation(Orientation orientation);
+
+ /**
+ * Gets the orientation of the slider. A slider can be drawn vertically
+ * or horizontally.
+ *
+ * @return The orientation of the slider.
+ * @see setOrientation
+ */
+ Orientation getOrientation() const;
+
+ /**
+ * Sets the step length. The step length is used when the keys LEFT
+ * and RIGHT are pressed to step in the scale.
+ *
+ * @param length The step length.
+ * @see getStepLength
+ */
+ void setStepLength(double length);
+
+ /**
+ * Gets the step length. The step length is used when the keys LEFT
+ * and RIGHT are pressed to step in the scale.
+ *
+ * @return the step length.
+ * @see setStepLength
+ */
+ double getStepLength() const;
+
+ protected:
+ /**
+ * Converts a marker position to a value in the scale.
+ *
+ * @param position The position to convert.
+ * @return A scale value corresponding to the position.
+ * @see valueToMarkerPosition
+ */
+ virtual double markerPositionToValue(int position) const;
+
+ /**
+ * Converts a value to a marker position.
+ *
+ * @param value The value to convert.
+ * @return A marker position corresponding to the value.
+ * @see markerPositionToValue
+ */
+ virtual int valueToMarkerPosition(double value) const;
+
+ /**
+ * Gets the marker position of the current selected value.
+ *
+ * @return The marker position of the current selected value.
+ */
+ virtual int getMarkerPosition() const;
+
+ /**
+ * True if the slider is dragged, false otherwise.
+ */
+ bool mDragged;
+
+ /**
+ * Holds the current selected value.
+ */
+ double mValue;
+
+ /**
+ * Holds the step length. The step length is used when the keys LEFT
+ * and RIGHT are pressed to step in the scale.
+ */
+ double mStepLength;
+
+ /**
+ * Holds the length of the marker.
+ */
+ int mMarkerLength;
+
+ /**
+ * Holds the start value of the scale.
+ */
+ double mScaleStart;
+
+ /**
+ * Holds the end value of the scale.
+ */
+ double mScaleEnd;
+
+ /**
+ * Holds the orientation of the slider. A slider can be drawn
+ * vertically or horizontally.
+ */
+ Orientation mOrientation;
+ };
+} // namespace gcn
+
+#endif // end GCN_SLIDER_HPP
diff --git a/src/gui/base/widgets/textbox.cpp b/src/gui/base/widgets/textbox.cpp
new file mode 100644
index 000000000..2e9ca0563
--- /dev/null
+++ b/src/gui/base/widgets/textbox.cpp
@@ -0,0 +1,345 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/textbox.hpp"
+
+#include "gui/base/basiccontainer.hpp"
+#include "gui/base/font.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/key.hpp"
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ TextBox::TextBox() :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mTextRows(),
+ mCaretColumn(0),
+ mCaretRow(0),
+ mEditable(true),
+ mOpaque(true)
+ {
+ setText("");
+ setFocusable(true);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ adjustSize();
+ }
+
+ TextBox::TextBox(const std::string& text) :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mTextRows(),
+ mCaretColumn(0),
+ mCaretRow(0),
+ mEditable(true),
+ mOpaque(true)
+ {
+ setText(text);
+ setFocusable(true);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ adjustSize();
+ }
+
+ void TextBox::setText(const std::string& text)
+ {
+ mCaretColumn = 0;
+ mCaretRow = 0;
+
+ mTextRows.clear();
+
+ size_t pos, lastPos = 0;
+ int length;
+ do
+ {
+ pos = text.find("\n", lastPos);
+
+ if (pos != std::string::npos)
+ length = static_cast<int>(pos - lastPos);
+ else
+ length = static_cast<int>(text.size() - lastPos);
+ std::string sub = text.substr(lastPos, length);
+ mTextRows.push_back(sub);
+ lastPos = pos + 1;
+ } while (pos != std::string::npos);
+
+ adjustSize();
+ }
+
+/*
+ void TextBox::draw(Graphics* graphics)
+ {
+ }
+*/
+
+ void TextBox::drawCaret(Graphics* graphics, int x, int y)
+ {
+ graphics->setColor(mForegroundColor);
+ graphics->drawLine(x, getFont()->getHeight() + y, x, y);
+ }
+
+ void TextBox::mousePressed(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.getButton() == MouseEvent::LEFT)
+ {
+ mCaretRow = mouseEvent.getY() / getFont()->getHeight();
+
+ const int sz = static_cast<int>(mTextRows.size());
+ if (mCaretRow >= sz)
+ mCaretRow = sz - 1;
+
+ mCaretColumn = getFont()->getStringIndexAt(
+ mTextRows[mCaretRow], mouseEvent.getX());
+ }
+ }
+
+ void TextBox::mouseDragged(MouseEvent& mouseEvent)
+ {
+ mouseEvent.consume();
+ }
+
+ void TextBox::keyPressed(KeyEvent& keyEvent A_UNUSED)
+ {
+ }
+
+ void TextBox::adjustSize()
+ {
+ int width = 0;
+ for (size_t i = 0, sz = mTextRows.size(); i < sz; ++i)
+ {
+ const int w = getFont()->getWidth(mTextRows[i]);
+ if (width < w)
+ width = w;
+ }
+
+ setWidth(width + 1);
+ setHeight(static_cast<int>(getFont()->getHeight() * mTextRows.size()));
+ }
+
+ void TextBox::setCaretPosition(unsigned int position)
+ {
+ for (int row = 0, sz = static_cast<int>(mTextRows.size());
+ row < sz; row ++)
+ {
+ if (position <= mTextRows[row].size())
+ {
+ mCaretRow = row;
+ mCaretColumn = position;
+ return; // we are done
+ }
+ else
+ {
+ position--;
+ }
+ }
+
+ // position beyond end of text
+ mCaretRow = static_cast<int>(mTextRows.size() - 1);
+ mCaretColumn = static_cast<int>(mTextRows[mCaretRow].size());
+ }
+
+ unsigned int TextBox::getCaretPosition() const
+ {
+ int pos = 0, row;
+
+ for (row = 0; row < mCaretRow; row++)
+ pos += static_cast<int>(mTextRows[row].size());
+
+ return pos + mCaretColumn;
+ }
+
+ void TextBox::setCaretRowColumn(int row, int column)
+ {
+ setCaretRow(row);
+ setCaretColumn(column);
+ }
+
+ void TextBox::setCaretRow(int row)
+ {
+ mCaretRow = row;
+
+ const int sz = static_cast<int>(mTextRows.size());
+ if (mCaretRow >= sz)
+ mCaretRow = sz - 1;
+
+ if (mCaretRow < 0)
+ mCaretRow = 0;
+
+ setCaretColumn(mCaretColumn);
+ }
+
+ unsigned int TextBox::getCaretRow() const
+ {
+ return mCaretRow;
+ }
+
+ void TextBox::setCaretColumn(int column)
+ {
+ mCaretColumn = column;
+
+ const int sz = static_cast<int>(mTextRows[mCaretRow].size());
+ if (mCaretColumn > sz)
+ mCaretColumn = sz;
+
+ if (mCaretColumn < 0)
+ mCaretColumn = 0;
+ }
+
+ unsigned int TextBox::getCaretColumn() const
+ {
+ return mCaretColumn;
+ }
+
+ const std::string& TextBox::getTextRow(int row) const
+ {
+ return mTextRows[row];
+ }
+
+ void TextBox::setTextRow(int row, const std::string& text)
+ {
+ mTextRows[row] = text;
+
+ if (mCaretRow == row)
+ setCaretColumn(mCaretColumn);
+
+ adjustSize();
+ }
+
+ unsigned int TextBox::getNumberOfRows() const
+ {
+ return static_cast<int>(mTextRows.size());
+ }
+
+ std::string TextBox::getText() const
+ {
+ if (mTextRows.empty())
+ return std::string("");
+
+ int i;
+ std::string text;
+
+ const int sz = static_cast<int>(mTextRows.size());
+ for (i = 0; i < sz - 1; ++ i)
+ text.append(mTextRows[i]).append("\n");
+ text.append(mTextRows[i]);
+
+ return text;
+ }
+
+ void TextBox::fontChanged()
+ {
+ adjustSize();
+ }
+
+ void TextBox::scrollToCaret()
+ {
+ Rectangle scroll;
+ scroll.x = getFont()->getWidth(
+ mTextRows[mCaretRow].substr(0, mCaretColumn));
+ scroll.y = getFont()->getHeight() * mCaretRow;
+ scroll.width = getFont()->getWidth(" ");
+
+ // add 2 for some extra space
+ scroll.height = getFont()->getHeight() + 2;
+
+ showPart(scroll);
+ }
+
+ void TextBox::setEditable(bool editable)
+ {
+ mEditable = editable;
+ }
+
+ bool TextBox::isEditable() const
+ {
+ return mEditable;
+ }
+
+ void TextBox::addRow(const std::string &row)
+ {
+ mTextRows.push_back(row);
+ adjustSize();
+ }
+
+ bool TextBox::isOpaque()
+ {
+ return mOpaque;
+ }
+
+ void TextBox::setOpaque(bool opaque)
+ {
+ mOpaque = opaque;
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/textbox.hpp b/src/gui/base/widgets/textbox.hpp
new file mode 100644
index 000000000..0a540a2c1
--- /dev/null
+++ b/src/gui/base/widgets/textbox.hpp
@@ -0,0 +1,310 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_TEXTBOX_HPP
+#define GCN_TEXTBOX_HPP
+
+#include <ctime>
+#include <string>
+#include <vector>
+
+#include "gui/base/keylistener.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widget.hpp"
+
+namespace gcn
+{
+ /**
+ * An implementation of a text box where a user can enter text that contains of many lines.
+ */
+ class TextBox:
+ public Widget,
+ public MouseListener,
+ public KeyListener
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ TextBox();
+
+ /**
+ * Constructor.
+ *
+ * @param text The default text of the text box.
+ */
+ explicit TextBox(const std::string& text);
+
+ A_DELETE_COPY(TextBox)
+
+ /**
+ * Sets the text of the text box.
+ *
+ * @param text The text of the text box.
+ * @see getText
+ */
+ void setText(const std::string& text);
+
+ /**
+ * Gets the text of the text box.
+ *
+ * @return The text of the text box.
+ * @see setText
+ */
+ std::string getText() const;
+
+ /**
+ * Gets a certain row from the text.
+ *
+ * @param row The number of the row to get from the text.
+ * @return A row from the text of the text box.
+ * @see setTextRow
+ */
+ const std::string& getTextRow(int row) const;
+
+ /**
+ * Sets the text of a certain row of the text.
+ *
+ * @param row The number of the row to set in the text.
+ * @param text The text to set in the given row number.
+ * @see getTextRow
+ */
+ void setTextRow(int row, const std::string& text);
+
+ /**
+ * Gets the number of rows in the text.
+ *
+ * @return The number of rows in the text.
+ */
+ unsigned int getNumberOfRows() const;
+
+ /**
+ * Gets the caret position in the text.
+ *
+ * @return The caret position in the text.
+ * @see setCaretPosition
+ */
+ unsigned int getCaretPosition() const;
+
+ /**
+ * Sets the position of the caret in the text.
+ *
+ * @param position the positon of the caret.
+ * @see getCaretPosition
+ */
+ void setCaretPosition(unsigned int position);
+
+ /**
+ * Gets the row number where the caret is currently located.
+ *
+ * @return The row number where the caret is currently located.
+ * @see setCaretRow
+ */
+ unsigned int getCaretRow() const;
+
+ /**
+ * Sets the row where the caret should be currently located.
+ *
+ * @param The row where the caret should be currently located.
+ * @see getCaretRow
+ */
+ void setCaretRow(int row);
+
+ /**
+ * Gets the column where the caret is currently located.
+ *
+ * @return The column where the caret is currently located.
+ * @see setCaretColumn
+ */
+ unsigned int getCaretColumn() const;
+
+ /**
+ * Sets the column where the caret should be currently located.
+ *
+ * @param The column where the caret should be currently located.
+ * @see getCaretColumn
+ */
+ void setCaretColumn(int column);
+
+ /**
+ * Sets the row and the column where the caret should be curretly
+ * located.
+ *
+ * @param row The row where the caret should be currently located.
+ * @param column The column where the caret should be currently located.
+ * @see getCaretRow, getCaretColumn
+ */
+ void setCaretRowColumn(int row, int column);
+
+ /**
+ * Scrolls the text to the caret if the text box is in a scroll area.
+ *
+ * @see ScrollArea
+ */
+ virtual void scrollToCaret();
+
+ /**
+ * Checks if the text box is editable.
+ *
+ * @return True it the text box is editable, false otherwise.
+ * @see setEditable
+ */
+ bool isEditable() const;
+
+ /**
+ * Sets the text box to be editable or not.
+ *
+ * @param editable True if the text box should be editable, false otherwise.
+ */
+ void setEditable(bool editable);
+
+ /**
+ * Adds a row of text to the end of the text.
+ *
+ * @param row The row to add.
+ */
+ virtual void addRow(const std::string &row);
+
+ /**
+ * Checks if the text box is opaque. An opaque text box will draw
+ * it's background and it's text. A non opaque text box only draw it's
+ * text making it transparent.
+ *
+ * @return True if the text box is opaque, false otherwise.
+ * @see setOpaque
+ */
+ bool isOpaque();
+
+ /**
+ * Sets the text box to be opaque or not. An opaque text box will draw
+ * it's background and it's text. A non opaque text box only draw it's
+ * text making it transparent.
+ *
+ * @param opaque True if the text box should be opaque, false otherwise.
+ * @see isOpaque
+ */
+ void setOpaque(bool opaque);
+
+
+ // Inherited from Widget
+
+// virtual void draw(Graphics* graphics);
+
+ virtual void fontChanged();
+
+
+ // Inherited from KeyListener
+
+ virtual void keyPressed(KeyEvent& keyEvent) override;
+
+
+ // Inherited from MouseListener
+
+ virtual void mousePressed(MouseEvent& mouseEvent) override;
+
+ virtual void mouseDragged(MouseEvent& mouseEvent) override;
+
+ protected:
+ /**
+ * Draws the caret. Overloaded this method if you want to
+ * change the style of the caret.
+ *
+ * @param graphics a Graphics object to draw with.
+ * @param x the x position.
+ * @param y the y position.
+ */
+ virtual void drawCaret(Graphics* graphics, int x, int y);
+
+ /**
+ * Adjusts the text box's size to fit the text.
+ */
+ virtual void adjustSize();
+
+ /**
+ * Holds all the rows of the text.
+ */
+ std::vector<std::string> mTextRows;
+
+ /**
+ * Holds the current column of the caret.
+ */
+ int mCaretColumn;
+
+ /**
+ * Holds the current row of the caret.
+ */
+ int mCaretRow;
+
+ /**
+ * True if the text box is editable, false otherwise.
+ */
+ bool mEditable;
+
+ /**
+ * True if the text box is editable, false otherwise.
+ */
+ bool mOpaque;
+ };
+} // namespace gcn
+
+#endif // end GCN_TEXTBOX_HPP
diff --git a/src/gui/base/widgets/textfield.cpp b/src/gui/base/widgets/textfield.cpp
new file mode 100644
index 000000000..586e49663
--- /dev/null
+++ b/src/gui/base/widgets/textfield.cpp
@@ -0,0 +1,165 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/textfield.hpp"
+
+#include "gui/base/font.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/key.hpp"
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ TextField::TextField() :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mText(),
+ mCaretPosition(0),
+ mXScroll(0)
+ {
+ setFocusable(true);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ }
+
+ TextField::TextField(const std::string& text) :
+ gcn::Widget(),
+ gcn::MouseListener(),
+ gcn::KeyListener(),
+ mText(text),
+ mCaretPosition(0),
+ mXScroll(0)
+ {
+ adjustSize();
+
+ setFocusable(true);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ }
+
+ void TextField::setText(const std::string& text)
+ {
+ const size_t sz = text.size();
+ if (sz < mCaretPosition)
+ mCaretPosition = sz;
+ mText = text;
+ }
+
+ void TextField::drawCaret(Graphics* graphics A_UNUSED, int x A_UNUSED)
+ {
+ }
+
+ void TextField::mousePressed(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.getButton() == MouseEvent::LEFT)
+ {
+ mCaretPosition = getFont()->getStringIndexAt(
+ mText, mouseEvent.getX() + mXScroll);
+ fixScroll();
+ }
+ }
+
+ void TextField::mouseDragged(MouseEvent& mouseEvent)
+ {
+ mouseEvent.consume();
+ }
+
+ void TextField::adjustSize()
+ {
+ }
+
+ void TextField::adjustHeight()
+ {
+ }
+
+ void TextField::fixScroll()
+ {
+ }
+
+ void TextField::setCaretPosition(unsigned int position A_UNUSED)
+ {
+ }
+
+ unsigned int TextField::getCaretPosition() const
+ {
+ return mCaretPosition;
+ }
+
+ const std::string& TextField::getText() const
+ {
+ return mText;
+ }
+
+ void TextField::fontChanged()
+ {
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/textfield.hpp b/src/gui/base/widgets/textfield.hpp
new file mode 100644
index 000000000..bc227eb55
--- /dev/null
+++ b/src/gui/base/widgets/textfield.hpp
@@ -0,0 +1,190 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_TEXTFIELD_HPP
+#define GCN_TEXTFIELD_HPP
+
+#include "gui/base/keylistener.hpp"
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widget.hpp"
+
+#include <string>
+
+namespace gcn
+{
+ /**
+ * An implementation of a text field where a user can enter a line of text.
+ */
+ class TextField:
+ public Widget,
+ public MouseListener,
+ public KeyListener
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ TextField();
+
+ /**
+ * Constructor. The text field will be automatically resized
+ * to fit the text.
+ *
+ * @param text The default text of the text field.
+ */
+ explicit TextField(const std::string& text);
+
+ A_DELETE_COPY(TextField)
+
+ /**
+ * Sets the text of the text field.
+ *
+ * @param text The text of the text field.
+ * @see getText
+ */
+ void setText(const std::string& text);
+
+ /**
+ * Gets the text of the text field.
+ *
+ * @return The text of the text field.
+ * @see setText
+ */
+ const std::string& getText() const;
+
+ /**
+ * Adjusts the size of the text field to fit the text.
+ */
+ void adjustSize();
+
+ /**
+ * Adjusts the height of the text field to fit caption.
+ */
+ void adjustHeight();
+
+ /**
+ * Sets the caret position. As there is only one line of text
+ * in a text field the position is the caret's x coordinate.
+ *
+ * @param position The caret position.
+ * @see getCaretPosition
+ */
+ void setCaretPosition(unsigned int position);
+
+ /**
+ * Gets the caret position. As there is only one line of text
+ * in a text field the position is the caret's x coordinate.
+ *
+ * @return The caret position.
+ * @see setCaretPosition
+ */
+ unsigned int getCaretPosition() const;
+
+
+ // Inherited from Widget
+
+ virtual void fontChanged();
+
+ // Inherited from MouseListener
+
+ virtual void mousePressed(MouseEvent& mouseEvent) override;
+
+ virtual void mouseDragged(MouseEvent& mouseEvent) override;
+
+ protected:
+ /**
+ * Draws the caret. Overloaded this method if you want to
+ * change the style of the caret.
+ *
+ * @param graphics the Graphics object to draw with.
+ * @param x the caret's x-position.
+ */
+ virtual void drawCaret(Graphics* graphics, int x);
+
+ /**
+ * Scrolls the text horizontally so that the caret shows if needed.
+ * The method is used any time a user types in the text field so the
+ * caret always will be shown.
+ */
+ void fixScroll();
+
+ /**
+ * Holds the text of the text box.
+ */
+ std::string mText;
+
+ /**
+ * Holds the caret position.
+ */
+ unsigned int mCaretPosition;
+
+ /**
+ * Holds the amount scrolled in x. If a user types more characters than
+ * the text field can display, due to the text field being to small, the
+ * text needs to scroll in order to show the last type character.
+ */
+ int mXScroll;
+ };
+} // namespace gcn
+
+#endif // end GCN_TEXTFIELD_HPP
diff --git a/src/gui/base/widgets/window.cpp b/src/gui/base/widgets/window.cpp
new file mode 100644
index 000000000..c7a108ab8
--- /dev/null
+++ b/src/gui/base/widgets/window.cpp
@@ -0,0 +1,233 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/base/widgets/window.hpp"
+
+#include "gui/base/exception.hpp"
+#include "gui/base/font.hpp"
+#include "gui/base/graphics.hpp"
+#include "gui/base/mouseinput.hpp"
+
+#include "debug.h"
+
+namespace gcn
+{
+ Window::Window() :
+ Container(),
+ gcn::MouseListener(),
+ mCaption(),
+ mAlignment(Graphics::CENTER),
+ mPadding(2),
+ mTitleBarHeight(16),
+ mMovable(true),
+ mOpaque(true),
+ mDragOffsetX(0),
+ mDragOffsetY(0),
+ mMoved(false)
+ {
+ mFrameSize = 1;
+ addMouseListener(this);
+ }
+
+ Window::Window(const std::string& caption) :
+ Container(),
+ gcn::MouseListener(),
+ mCaption(caption),
+ mAlignment(Graphics::CENTER),
+ mPadding(2),
+ mTitleBarHeight(16),
+ mMovable(true),
+ mOpaque(true),
+ mDragOffsetX(0),
+ mDragOffsetY(0),
+ mMoved(false)
+ {
+ mFrameSize = 1;
+ addMouseListener(this);
+ }
+
+ Window::~Window()
+ {
+ }
+
+ void Window::setPadding(unsigned int padding)
+ {
+ mPadding = padding;
+ }
+
+ unsigned int Window::getPadding() const
+ {
+ return mPadding;
+ }
+
+ void Window::setTitleBarHeight(unsigned int height)
+ {
+ mTitleBarHeight = height;
+ }
+
+ unsigned int Window::getTitleBarHeight()
+ {
+ return mTitleBarHeight;
+ }
+
+ void Window::setCaption(const std::string& caption)
+ {
+ mCaption = caption;
+ }
+
+ const std::string& Window::getCaption() const
+ {
+ return mCaption;
+ }
+
+ void Window::setAlignment(Graphics::Alignment alignment)
+ {
+ mAlignment = alignment;
+ }
+
+ Graphics::Alignment Window::getAlignment() const
+ {
+ return mAlignment;
+ }
+
+ void Window::mousePressed(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.getSource() != this)
+ return;
+
+ if (getParent())
+ getParent()->moveToTop(this);
+
+ mDragOffsetX = mouseEvent.getX();
+ mDragOffsetY = mouseEvent.getY();
+
+ mMoved = mouseEvent.getY() <= static_cast<int>(mTitleBarHeight);
+ }
+
+ void Window::mouseReleased(MouseEvent& mouseEvent A_UNUSED)
+ {
+ mMoved = false;
+ }
+
+ void Window::mouseDragged(MouseEvent& mouseEvent)
+ {
+ if (mouseEvent.isConsumed() || mouseEvent.getSource() != this)
+ return;
+
+ if (isMovable() && mMoved)
+ {
+ setPosition(mouseEvent.getX() - mDragOffsetX + getX(),
+ mouseEvent.getY() - mDragOffsetY + getY());
+ }
+
+ mouseEvent.consume();
+ }
+
+ Rectangle Window::getChildrenArea()
+ {
+ return Rectangle(getPadding(),
+ getTitleBarHeight(),
+ getWidth() - getPadding() * 2,
+ getHeight() - getPadding() - getTitleBarHeight());
+ }
+
+ void Window::setMovable(bool movable)
+ {
+ mMovable = movable;
+ }
+
+ bool Window::isMovable() const
+ {
+ return mMovable;
+ }
+
+ void Window::setOpaque(bool opaque)
+ {
+ mOpaque = opaque;
+ }
+
+ bool Window::isOpaque()
+ {
+ return mOpaque;
+ }
+
+ void Window::resizeToContent()
+ {
+ int w = 0, h = 0;
+ for (WidgetListConstIterator it = mWidgets.begin();
+ it != mWidgets.end(); ++ it)
+ {
+ if ((*it)->getX() + (*it)->getWidth() > w)
+ w = (*it)->getX() + (*it)->getWidth();
+
+ if ((*it)->getY() + (*it)->getHeight() > h)
+ h = (*it)->getY() + (*it)->getHeight();
+ }
+
+ setSize(w + 2* getPadding(), h + getPadding() + getTitleBarHeight());
+ }
+} // namespace gcn
diff --git a/src/gui/base/widgets/window.hpp b/src/gui/base/widgets/window.hpp
new file mode 100644
index 000000000..9c7e6bcbf
--- /dev/null
+++ b/src/gui/base/widgets/window.hpp
@@ -0,0 +1,269 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011-2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * Copyright (c) 2004 - 2008 Olof Naessén and Per Larsson
+ *
+ *
+ * Per Larsson a.k.a finalman
+ * Olof Naessén a.k.a jansem/yakslem
+ *
+ * Visit: http://guichan.sourceforge.net
+ *
+ * License: (BSD)
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of Guichan nor the names of its contributors may
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GCN_WINDOW_HPP
+#define GCN_WINDOW_HPP
+
+#include <string>
+
+#include "gui/base/mouselistener.hpp"
+#include "gui/base/widgets/container.hpp"
+
+namespace gcn
+{
+ /**
+ * An implementation of a movable window that can contain other widgets.
+ */
+ class Window : public Container,
+ public MouseListener
+ {
+ public:
+ /**
+ * Constructor.
+ */
+ Window();
+
+ /**
+ * Constructor. The window will be automatically resized in height
+ * to fit the caption.
+ *
+ * @param caption the caption of the window.
+ */
+ explicit Window(const std::string& caption);
+
+ A_DELETE_COPY(Window)
+
+ /**
+ * Destructor.
+ */
+ virtual ~Window();
+
+ /**
+ * Sets the caption of the window.
+ *
+ * @param caption The caption of the window.
+ * @see getCaption
+ */
+ void setCaption(const std::string& caption);
+
+ /**
+ * Gets the caption of the window.
+ *
+ * @return the caption of the window.
+ * @see setCaption
+ */
+ const std::string& getCaption() const;
+
+ /**
+ * Sets the alignment of the caption.
+ *
+ * @param alignment The alignment of the caption.
+ * @see getAlignment, Graphics
+ */
+ void setAlignment(Graphics::Alignment alignment);
+
+ /**
+ * Gets the alignment of the caption.
+ *
+ * @return The alignment of caption.
+ * @see setAlignment, Graphics
+ */
+ Graphics::Alignment getAlignment() const;
+
+ /**
+ * Sets the padding of the window. The padding is the distance between the
+ * window border and the content.
+ *
+ * @param padding The padding of the window.
+ * @see getPadding
+ */
+ void setPadding(unsigned int padding);
+
+ /**
+ * Gets the padding of the window. The padding is the distance between the
+ * window border and the content.
+ *
+ * @return The padding of the window.
+ * @see setPadding
+ */
+ unsigned int getPadding() const;
+
+ /**
+ * Sets the title bar height.
+ *
+ * @param height The title height value.
+ * @see getTitleBarHeight
+ */
+ void setTitleBarHeight(unsigned int height);
+
+ /**
+ * Gets the title bar height.
+ *
+ * @return The title bar height.
+ * @see setTitleBarHeight
+ */
+ unsigned int getTitleBarHeight();
+
+ /**
+ * Sets the window to be moveble or not.
+ *
+ * @param movable True if the window should be movable, false otherwise.
+ * @see isMovable
+ */
+ void setMovable(bool movable);
+
+ /**
+ * Checks if the window is movable.
+ *
+ * @return True if the window is movable, false otherwise.
+ * @see setMovable
+ */
+ bool isMovable() const;
+
+ /**
+ * Sets the window to be opaque or not. An opaque window will draw it's background
+ * and it's content. A non opaque window will only draw it's content.
+ *
+ * @param opaque True if the window should be opaque, false otherwise.
+ * @see isOpaque
+ */
+ void setOpaque(bool opaque);
+
+ /**
+ * Checks if the window is opaque.
+ *
+ * @return True if the window is opaque, false otherwise.
+ * @see setOpaque
+ */
+ bool isOpaque();
+
+ /**
+ * Resizes the window to fit the content.
+ */
+ virtual void resizeToContent();
+
+ // Inherited from BasicContainer
+
+ virtual Rectangle getChildrenArea();
+
+ // Inherited from MouseListener
+
+ virtual void mousePressed(MouseEvent& mouseEvent) override;
+
+ virtual void mouseDragged(MouseEvent& mouseEvent) override;
+
+ virtual void mouseReleased(MouseEvent& mouseEvent) override;
+
+ protected:
+ /**
+ * Holds the caption of the window.
+ */
+ std::string mCaption;
+
+ /**
+ * Holds the alignment of the caption.
+ */
+ Graphics::Alignment mAlignment;
+
+ /**
+ * Holds the padding of the window.
+ */
+ unsigned int mPadding;
+
+ /**
+ * Holds the title bar height of the window.
+ */
+ unsigned int mTitleBarHeight;
+
+ /**
+ * True if the window is movable, false otherwise.
+ */
+ bool mMovable;
+
+ /**
+ * True if the window is opaque, false otherwise.
+ */
+ bool mOpaque;
+
+ /**
+ * Holds a drag offset as an x coordinate where the drag of the window
+ * started if the window is being dragged. It's used to move the window
+ * correctly when dragged.
+ */
+ int mDragOffsetX;
+
+ /**
+ * Holds a drag offset as an y coordinate where the drag of the window
+ * started if the window is being dragged. It's used to move the window
+ * correctly when dragged.
+ */
+ int mDragOffsetY;
+
+ /**
+ * True if the window is being moved, false otherwise.
+ */
+ bool mMoved;
+ };
+} // namespace gcn
+
+#endif // end GCN_WINDOW_HPP