summaryrefslogtreecommitdiff
path: root/src/gui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/widgets')
-rw-r--r--src/gui/widgets/basiccontainer.cpp377
-rw-r--r--src/gui/widgets/basiccontainer.h215
-rw-r--r--src/gui/widgets/basiccontainer2.cpp129
-rw-r--r--src/gui/widgets/basiccontainer2.h174
-rw-r--r--src/gui/widgets/button.cpp150
-rw-r--r--src/gui/widgets/button.h161
-rw-r--r--src/gui/widgets/checkbox.cpp74
-rw-r--r--src/gui/widgets/checkbox.h106
-rw-r--r--src/gui/widgets/container.cpp2
-rw-r--r--src/gui/widgets/container.h4
-rw-r--r--src/gui/widgets/desktop.cpp28
-rw-r--r--src/gui/widgets/desktop.h11
-rw-r--r--src/gui/widgets/dropdown.cpp2
-rw-r--r--src/gui/widgets/dropdown.h4
-rw-r--r--src/gui/widgets/guitable.cpp8
-rw-r--r--src/gui/widgets/guitable.h2
-rw-r--r--src/gui/widgets/label.cpp57
-rw-r--r--src/gui/widgets/label.h97
-rw-r--r--src/gui/widgets/layout.cpp2
-rw-r--r--src/gui/widgets/layout.h11
-rw-r--r--src/gui/widgets/layouthelper.cpp4
-rw-r--r--src/gui/widgets/layouthelper.h4
-rw-r--r--src/gui/widgets/listbox.cpp118
-rw-r--r--src/gui/widgets/listbox.h179
-rw-r--r--src/gui/widgets/playerbox.cpp9
-rw-r--r--src/gui/widgets/playerbox.h7
-rw-r--r--src/gui/widgets/radiobutton.cpp118
-rw-r--r--src/gui/widgets/radiobutton.h147
-rw-r--r--src/gui/widgets/scrollarea.cpp438
-rw-r--r--src/gui/widgets/scrollarea.h417
-rw-r--r--src/gui/widgets/setupitem.cpp8
-rw-r--r--src/gui/widgets/slider.cpp171
-rw-r--r--src/gui/widgets/slider.h242
-rw-r--r--src/gui/widgets/tabbedarea.cpp10
-rw-r--r--src/gui/widgets/tabbedarea.h8
-rw-r--r--src/gui/widgets/tabs/chattab.cpp4
-rw-r--r--src/gui/widgets/tabs/setup_colors.cpp22
-rw-r--r--src/gui/widgets/tabs/setup_players.cpp5
-rw-r--r--src/gui/widgets/tabs/setup_relations.cpp2
-rw-r--r--src/gui/widgets/tabs/setup_video.cpp14
-rw-r--r--src/gui/widgets/tabs/setup_visual.cpp7
-rw-r--r--src/gui/widgets/tabs/tab.cpp2
-rw-r--r--src/gui/widgets/tabs/tab.h4
-rw-r--r--src/gui/widgets/textbox.cpp244
-rw-r--r--src/gui/widgets/textbox.h254
-rw-r--r--src/gui/widgets/textfield.cpp220
-rw-r--r--src/gui/widgets/textfield.h116
-rw-r--r--src/gui/widgets/widget.h4
-rw-r--r--src/gui/widgets/window.cpp6
-rw-r--r--src/gui/widgets/window.h6
50 files changed, 4056 insertions, 348 deletions
diff --git a/src/gui/widgets/basiccontainer.cpp b/src/gui/widgets/basiccontainer.cpp
new file mode 100644
index 000000000..d3dd62fc7
--- /dev/null
+++ b/src/gui/widgets/basiccontainer.cpp
@@ -0,0 +1,377 @@
+/*
+ * 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.
+ */
+
+#include "gui/widgets/basiccontainer.h"
+
+#include <algorithm>
+
+#include "debug.h"
+
+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;
+ }
+ }
+}
+
+void BasicContainer::moveToBottom(Widget* widget)
+{
+ WidgetListIterator iter;
+ iter = std::find(mWidgets.begin(), mWidgets.end(), widget);
+
+ if (iter == mWidgets.end())
+ return;
+
+ mWidgets.erase(iter);
+ mWidgets.insert(mWidgets.begin(), widget);
+}
+
+void BasicContainer::death(const Event& event)
+{
+ WidgetListIterator iter;
+ iter = std::find(mWidgets.begin(), mWidgets.end(), event.getSource());
+
+ if (iter == mWidgets.end())
+ return;
+
+ mWidgets.erase(iter);
+}
+
+Rect BasicContainer::getChildrenArea()
+{
+ return Rect(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 Rect 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;
+ }
+ }
+}
+
+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)
+ {
+ Rect 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 *const widget, Rect area)
+{
+ const Rect 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;
+}
diff --git a/src/gui/widgets/basiccontainer.h b/src/gui/widgets/basiccontainer.h
new file mode 100644
index 000000000..6e753a445
--- /dev/null
+++ b/src/gui/widgets/basiccontainer.h
@@ -0,0 +1,215 @@
+/*
+ * 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 GUI_WIDGETS_BASICCONTAINER_H
+#define GUI_WIDGETS_BASICCONTAINER_H
+
+#include <vector>
+
+#include "gui/widgets/widget.h"
+
+#include "listeners/deathlistener.h"
+
+/**
+ * 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:
+ explicit BasicContainer(const Widget2 *const widget) :
+ Widget(widget),
+ DeathListener(),
+ 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 *const widget, Rect area);
+
+ // Inherited from Widget
+
+ virtual void moveToTop(Widget* widget);
+
+ virtual void moveToBottom(Widget* widget);
+
+ virtual Rect 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;
+};
+
+#endif // GUI_WIDGETS_BASICCONTAINER_H
diff --git a/src/gui/widgets/basiccontainer2.cpp b/src/gui/widgets/basiccontainer2.cpp
new file mode 100644
index 000000000..9bd4d1593
--- /dev/null
+++ b/src/gui/widgets/basiccontainer2.cpp
@@ -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.
+ */
+
+/*
+ * For comments regarding functions please see the header file.
+ */
+
+#include "gui/widgets/basiccontainer2.h"
+
+#include "debug.h"
+
+BasicContainer2::BasicContainer2(const Widget2 *const widget) :
+ BasicContainer(widget),
+ mOpaque(true)
+{
+}
+
+BasicContainer2::~BasicContainer2()
+{
+}
+
+void BasicContainer2::draw(Graphics* graphics)
+{
+ BLOCK_START("BasicContainer2::draw")
+ if (isOpaque())
+ {
+ graphics->setColor(getBaseColor());
+ graphics->fillRectangle(Rect(0, 0, getWidth(), getHeight()));
+ }
+
+ drawChildren(graphics);
+ BLOCK_END("BasicContainer2::draw")
+}
+
+void BasicContainer2::setOpaque(bool opaque)
+{
+ mOpaque = opaque;
+}
+
+bool BasicContainer2::isOpaque() const
+{
+ return mOpaque;
+}
+
+void BasicContainer2::add(Widget* widget)
+{
+ BasicContainer::add(widget);
+}
+
+void BasicContainer2::add(Widget* widget, int x, int y)
+{
+ widget->setPosition(x, y);
+ BasicContainer::add(widget);
+}
+
+void BasicContainer2::remove(Widget* widget)
+{
+ BasicContainer::remove(widget);
+}
+
+void BasicContainer2::clear()
+{
+ BasicContainer::clear();
+}
+
+Widget* BasicContainer2::findWidgetById(const std::string &id)
+{
+ return BasicContainer::findWidgetById(id);
+}
diff --git a/src/gui/widgets/basiccontainer2.h b/src/gui/widgets/basiccontainer2.h
new file mode 100644
index 000000000..c6f1d996b
--- /dev/null
+++ b/src/gui/widgets/basiccontainer2.h
@@ -0,0 +1,174 @@
+/*
+ * 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 GUI_WIDGETS_BASICCONTAINER2_H
+#define GUI_WIDGETS_BASICCONTAINER2_H
+
+#include "gui/widgets/basiccontainer.h"
+
+/**
+ * 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 BasicContainer2: public BasicContainer
+{
+ public:
+ /**
+ * Constructor. A container is opauqe as default, if you want a
+ * none opaque container call setQpaque(false).
+ *
+ * @see setOpaque, isOpaque
+ */
+ explicit BasicContainer2(const Widget2 *const widget);
+
+ /**
+ * Destructor.
+ */
+ virtual ~BasicContainer2();
+
+ /**
+ * 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;
+};
+
+#endif // GUI_WIDGETS_BASICCONTAINER2_H
diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp
index 3cb6d823d..308c75413 100644
--- a/src/gui/widgets/button.cpp
+++ b/src/gui/widgets/button.cpp
@@ -20,6 +20,49 @@
* 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.
+ */
+
#include "gui/widgets/button.h"
#include "client.h"
@@ -53,8 +96,17 @@ static std::string const data[Button::BUTTON_COUNT] =
Skin *Button::button[BUTTON_COUNT];
Button::Button(const Widget2 *const widget) :
- gcn::Button(widget),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ FocusListener(),
WidgetListener(),
+ mCaption(),
+ mHasMouse(false),
+ mKeyPressed(false),
+ mMousePressed(false),
+ mAlignment(Graphics::CENTER),
+ mSpacing(4),
mDescription(),
mVertexes2(new ImageCollection),
mEnabledColor(getThemeColor(Theme::BUTTON)),
@@ -86,8 +138,17 @@ Button::Button(const Widget2 *const widget,
const std::string &restrict caption,
const std::string &restrict actionEventId,
ActionListener *const listener) :
- gcn::Button(widget, caption),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ FocusListener(),
WidgetListener(),
+ mCaption(caption),
+ mHasMouse(false),
+ mKeyPressed(false),
+ mMousePressed(false),
+ mAlignment(Graphics::CENTER),
+ mSpacing(4),
mDescription(),
mVertexes2(new ImageCollection),
mEnabledColor(getThemeColor(Theme::BUTTON)),
@@ -125,8 +186,17 @@ Button::Button(const Widget2 *const widget,
const int imageWidth, const int imageHeight,
const std::string &restrict actionEventId,
ActionListener *const listener) :
- gcn::Button(widget, caption),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ FocusListener(),
WidgetListener(),
+ mCaption(caption),
+ mHasMouse(false),
+ mKeyPressed(false),
+ mMousePressed(false),
+ mAlignment(Graphics::CENTER),
+ mSpacing(4),
mDescription(),
mVertexes2(new ImageCollection),
mEnabledColor(getThemeColor(Theme::BUTTON)),
@@ -164,8 +234,17 @@ Button::Button(const Widget2 *const widget,
const int imageWidth, const int imageHeight,
const std::string &restrict actionEventId,
ActionListener *const listener) :
- gcn::Button(widget),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ FocusListener(),
WidgetListener(),
+ mCaption(),
+ mHasMouse(false),
+ mKeyPressed(false),
+ mMousePressed(false),
+ mAlignment(Graphics::CENTER),
+ mSpacing(4),
mDescription(),
mVertexes2(new ImageCollection),
mEnabledColor(getThemeColor(Theme::BUTTON)),
@@ -203,8 +282,17 @@ Button::Button(const Widget2 *const widget,
const std::string &restrict imageName,
const std::string &restrict actionEventId,
ActionListener *const listener) :
- gcn::Button(widget, caption),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ FocusListener(),
WidgetListener(),
+ mCaption(caption),
+ mHasMouse(false),
+ mKeyPressed(false),
+ mMousePressed(false),
+ mAlignment(Graphics::CENTER),
+ mSpacing(4),
mDescription(),
mVertexes2(new ImageCollection),
mEnabledColor(getThemeColor(Theme::BUTTON)),
@@ -239,10 +327,14 @@ Button::Button(const Widget2 *const widget,
void Button::init()
{
- setFrameSize(0);
-
+ addMouseListener(this);
+ addKeyListener(this);
+ addFocusListener(this);
addWidgetListener(this);
+ setFocusable(true);
+ setFrameSize(0);
+
if (mInstances == 0)
{
if (Theme::instance())
@@ -584,11 +676,6 @@ void Button::adjustSize()
}
}
-void Button::setCaption(const std::string& caption)
-{
- mCaption = caption;
-}
-
void Button::keyPressed(KeyEvent& keyEvent)
{
const int action = keyEvent.getActionId();
@@ -614,8 +701,45 @@ void Button::keyReleased(KeyEvent& keyEvent)
}
}
-
bool Button::isPressed2() const
{
return (mPressed || isPressed());
}
+
+bool Button::isPressed() const
+{
+ if (mMousePressed)
+ return mHasMouse;
+ else
+ return mKeyPressed;
+}
+
+void Button::focusLost(const Event& event A_UNUSED)
+{
+ mMousePressed = false;
+ mKeyPressed = false;
+}
+
+void Button::mousePressed(MouseEvent& mouseEvent)
+{
+ if (mouseEvent.getButton() == MouseEvent::LEFT)
+ {
+ mMousePressed = true;
+ mouseEvent.consume();
+ }
+}
+
+void Button::mouseEntered(MouseEvent& mouseEvent A_UNUSED)
+{
+ mHasMouse = true;
+}
+
+void Button::mouseExited(MouseEvent& mouseEvent A_UNUSED)
+{
+ mHasMouse = false;
+}
+
+void Button::mouseDragged(MouseEvent& mouseEvent)
+{
+ mouseEvent.consume();
+}
diff --git a/src/gui/widgets/button.h b/src/gui/widgets/button.h
index 039475150..6eba9b3c0 100644
--- a/src/gui/widgets/button.h
+++ b/src/gui/widgets/button.h
@@ -20,10 +20,57 @@
* 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 GUI_WIDGETS_BUTTON_H
#define GUI_WIDGETS_BUTTON_H
-#include "gui/base/widgets/button.hpp"
+#include "gui/widgets/widget.h"
+
+#include "listeners/focuslistener.h"
+#include "listeners/keylistener.h"
+#include "listeners/mouselistener.h"
#include "listeners/widgetlistener.h"
#include "localconsts.h"
@@ -40,7 +87,10 @@ const std::string BUTTON_PLAY = "buttonplay.png";
*
* \ingroup GUI
*/
-class Button final : public gcn::Button,
+class Button final : public Widget,
+ public MouseListener,
+ public KeyListener,
+ public FocusListener,
public WidgetListener
{
public:
@@ -139,14 +189,79 @@ class Button final : public gcn::Button,
void adjustSize();
- void setCaption(const std::string& caption);
-
void keyPressed(KeyEvent &keyEvent) override final;
void keyReleased(KeyEvent &keyEvent) override final;
bool isPressed2() const A_WARN_UNUSED;
+ /**
+ * 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)
+ { mCaption = caption; }
+
+ /**
+ * Gets the caption of the button.
+ *
+ * @return The caption of the button.
+ */
+ const std::string& getCaption() const
+ { return mCaption; }
+
+ /**
+ * 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)
+ { mAlignment = alignment; }
+
+ /**
+ * Gets the alignment of the caption.
+ *
+ * @return The alignment of the caption.
+ * @see setAlignment, Graphics
+ */
+ Graphics::Alignment getAlignment() const
+ { return mAlignment; }
+
+ /**
+ * 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)
+ { mSpacing = spacing; }
+
+ /**
+ * Gets the spacing between the border of the button and its caption.
+ *
+ * @return spacing.
+ * @see setSpacing
+ */
+ unsigned int getSpacing() const
+ { return mSpacing; }
+
+ void focusLost(const Event& event) override final;
+
+ void mousePressed(MouseEvent& mouseEvent) override final;
+
+ void mouseEntered(MouseEvent& mouseEvent) override final;
+
+ void mouseExited(MouseEvent& mouseEvent) override final;
+
+ void mouseDragged(MouseEvent& mouseEvent) override final;
+
enum
{
BUTTON_STANDARD = 0, // 0
@@ -157,12 +272,50 @@ class Button final : public gcn::Button,
};
private:
+ /**
+ * 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;
+
void init();
static Skin *button[BUTTON_COUNT]; /**< Button state graphics */
static int mInstances; /**< Number of button instances */
static float mAlpha;
+ /**
+ * 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;
+
std::string mDescription;
ImageCollection *mVertexes2;
Color mEnabledColor;
diff --git a/src/gui/widgets/checkbox.cpp b/src/gui/widgets/checkbox.cpp
index 9fb63b2e8..f01495bcf 100644
--- a/src/gui/widgets/checkbox.cpp
+++ b/src/gui/widgets/checkbox.cpp
@@ -20,12 +20,53 @@
* 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.
+ */
+
#include "gui/widgets/checkbox.h"
#include "client.h"
-#include "events/keyevent.h"
-
#include "input/keydata.h"
#include "resources/image.h"
@@ -44,7 +85,11 @@ CheckBox::CheckBox(const Widget2 *const widget,
const bool selected,
ActionListener *const listener,
const std::string &restrict eventId) :
- gcn::CheckBox(widget, caption, selected),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ mSelected(selected),
+ mCaption(),
mPadding(0),
mImagePadding(0),
mImageSize(9),
@@ -52,6 +97,12 @@ CheckBox::CheckBox(const Widget2 *const widget,
mHasMouse(false),
mDrawBox(true)
{
+ setCaption(caption);
+
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+
mForegroundColor2 = getThemeColor(Theme::CHECKBOX_OUTLINE);
if (instances == 0)
{
@@ -200,3 +251,20 @@ void CheckBox::adjustSize()
setWidth(mImagePadding + mImageSize + mSpacing
+ getFont()->getWidth(mCaption) + mPadding);
}
+
+void CheckBox::mouseClicked(MouseEvent& mouseEvent)
+{
+ if (mouseEvent.getButton() == MouseEvent::LEFT)
+ toggleSelected();
+}
+
+void CheckBox::mouseDragged(MouseEvent& mouseEvent)
+{
+ mouseEvent.consume();
+}
+
+void CheckBox::toggleSelected()
+{
+ mSelected = !mSelected;
+ distributeActionEvent();
+}
diff --git a/src/gui/widgets/checkbox.h b/src/gui/widgets/checkbox.h
index 28eadb75c..5711e766f 100644
--- a/src/gui/widgets/checkbox.h
+++ b/src/gui/widgets/checkbox.h
@@ -20,10 +20,56 @@
* 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 GUI_WIDGETS_CHECKBOX_H
#define GUI_WIDGETS_CHECKBOX_H
-#include "gui/base/widgets/checkbox.hpp"
+#include "listeners/keylistener.h"
+#include "listeners/mouselistener.h"
+
+#include "gui/widgets/widget.h"
#include "localconsts.h"
@@ -34,7 +80,9 @@ class Skin;
*
* \ingroup GUI
*/
-class CheckBox final : public gcn::CheckBox
+class CheckBox final : public Widget,
+ public MouseListener,
+ public KeyListener
{
public:
/**
@@ -82,7 +130,61 @@ class CheckBox final : public gcn::CheckBox
void adjustSize();
+ /**
+ * Checks if the check box is selected.
+ *
+ * @return True if the check box is selected, false otherwise.
+ * @see setSelected
+ */
+ bool isSelected() const
+ { return mSelected; }
+
+ /**
+ * 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(const bool selected)
+ { mSelected = selected; }
+
+ /**
+ * Gets the caption of the check box.
+ *
+ * @return The caption of the check box.
+ * @see setCaption
+ */
+ const std::string &getCaption() const
+ { return mCaption; }
+
+ /**
+ * 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)
+ { mCaption = caption; }
+
+ void mouseClicked(MouseEvent& mouseEvent) override final;
+
+ void mouseDragged(MouseEvent& mouseEvent) override final;
+
private:
+ void toggleSelected();
+
+ /**
+ * True if the check box is selected, false otherwise.
+ */
+ bool mSelected;
+
+ /**
+ * Holds the caption of the check box.
+ */
+ std::string mCaption;
+
int mPadding;
int mImagePadding;
int mImageSize;
diff --git a/src/gui/widgets/container.cpp b/src/gui/widgets/container.cpp
index 93d74dc8d..52d11c4e8 100644
--- a/src/gui/widgets/container.cpp
+++ b/src/gui/widgets/container.cpp
@@ -27,7 +27,7 @@
#include "debug.h"
Container::Container(const Widget2 *const widget) :
- gcn::Container(widget)
+ BasicContainer2(widget)
{
setOpaque(false);
}
diff --git a/src/gui/widgets/container.h b/src/gui/widgets/container.h
index 17d6b2af4..262d7327a 100644
--- a/src/gui/widgets/container.h
+++ b/src/gui/widgets/container.h
@@ -23,7 +23,7 @@
#ifndef GUI_WIDGETS_CONTAINER_H
#define GUI_WIDGETS_CONTAINER_H
-#include "gui/base/widgets/container.hpp"
+#include "gui/widgets/basiccontainer2.h"
/**
* A widget container.
@@ -34,7 +34,7 @@
*
* This container is also non-opaque by default.
*/
-class Container : public gcn::Container
+class Container : public BasicContainer2
{
public:
explicit Container(const Widget2 *const widget);
diff --git a/src/gui/widgets/desktop.cpp b/src/gui/widgets/desktop.cpp
index a77516c62..0ff1b17c9 100644
--- a/src/gui/widgets/desktop.cpp
+++ b/src/gui/widgets/desktop.cpp
@@ -24,7 +24,9 @@
#include "configuration.h"
#include "main.h"
-#include "gui/widgets/label.h"
+#include "gui/widgets/browserbox.h"
+
+#include "input/inputmanager.h"
#include "resources/image.h"
#include "resources/imagehelper.h"
@@ -35,9 +37,11 @@
Desktop::Desktop(const Widget2 *const widget) :
Container(widget),
+ LinkHandler(),
WidgetListener(),
mWallpaper(nullptr),
- mVersionLabel(nullptr),
+ mVersionLabel(new BrowserBox(this, BrowserBox::AUTO_WRAP, false,
+ "browserbox.xml")),
mSkin(nullptr),
mBackgroundColor(getThemeColor(Theme::BACKGROUND, 128)),
mBackgroundGrayColor(getThemeColor(Theme::BACKGROUND_GRAY)),
@@ -57,15 +61,16 @@ Desktop::Desktop(const Widget2 *const widget) :
const std::string appName = branding.getValue("appName", std::string());
if (appName.empty())
{
- mVersionLabel = new Label(this, FULL_VERSION);
+ mVersionLabel->addRow(FULL_VERSION);
}
else
{
- mVersionLabel = new Label(this, strprintf("%s (%s)", FULL_VERSION,
+ mVersionLabel->addRow(strprintf("%s (%s)", FULL_VERSION,
appName.c_str()));
}
-
- mVersionLabel->setBackgroundColor(getThemeColor(Theme::BACKGROUND, 128));
+ mVersionLabel->addRow("copyright",
+ "(C) ManaPlus developers, http://manaplus.org");
+ mVersionLabel->setLinkHandler(this);
}
Desktop::~Desktop()
@@ -100,6 +105,7 @@ void Desktop::reloadWallpaper()
void Desktop::widgetResized(const Event &event A_UNUSED)
{
+ mVersionLabel->setSize(getWidth(), getHeight());
setBestFittingWallpaper();
}
@@ -138,10 +144,6 @@ void Desktop::draw(Graphics *graphics)
graphics->fillRectangle(Rect(0, 0, width, height));
}
- // Draw a thin border under the application version...
- graphics->setColor(mBackgroundColor);
- graphics->fillRectangle(Rect(mVersionLabel->getDimension()));
-
Container::draw(graphics);
BLOCK_END("Desktop::draw")
}
@@ -198,3 +200,9 @@ void Desktop::setBestFittingWallpaper()
logger->log("Couldn't load %s as wallpaper", wallpaperName.c_str());
}
}
+
+void Desktop::handleLink(const std::string &link, MouseEvent *event A_UNUSED)
+{
+ if (link == "copyright")
+ inputManager.executeAction(Input::KEY_WINDOW_ABOUT);
+}
diff --git a/src/gui/widgets/desktop.h b/src/gui/widgets/desktop.h
index f0fd500ea..f3b0cd371 100644
--- a/src/gui/widgets/desktop.h
+++ b/src/gui/widgets/desktop.h
@@ -24,12 +24,14 @@
#include "gui/widgets/container.h"
+#include "gui/widgets/linkhandler.h"
+
#include "listeners/widgetlistener.h"
#include "localconsts.h"
+class BrowserBox;
class Image;
-class Label;
class Skin;
/**
@@ -46,7 +48,8 @@ class Skin;
* \ingroup GUI
*/
class Desktop final : public Container,
- private WidgetListener
+ public LinkHandler,
+ public WidgetListener
{
public:
explicit Desktop(const Widget2 *const widget);
@@ -66,11 +69,13 @@ class Desktop final : public Container,
void postInit();
+ void handleLink(const std::string &link,
+ MouseEvent *event) override final;
private:
void setBestFittingWallpaper();
Image *mWallpaper;
- Label *mVersionLabel;
+ BrowserBox *mVersionLabel;
Skin *mSkin;
Color mBackgroundColor;
Color mBackgroundGrayColor;
diff --git a/src/gui/widgets/dropdown.cpp b/src/gui/widgets/dropdown.cpp
index dfc17e17b..b1a3c4ac1 100644
--- a/src/gui/widgets/dropdown.cpp
+++ b/src/gui/widgets/dropdown.cpp
@@ -60,7 +60,7 @@ DropDown::DropDown(const Widget2 *const widget,
ActionListener *const listener,
const std::string &eventId):
ActionListener(),
- gcn::BasicContainer(widget),
+ BasicContainer(widget),
KeyListener(),
MouseListener(),
FocusListener(),
diff --git a/src/gui/widgets/dropdown.h b/src/gui/widgets/dropdown.h
index 8e463a2c1..2208880b3 100644
--- a/src/gui/widgets/dropdown.h
+++ b/src/gui/widgets/dropdown.h
@@ -23,7 +23,7 @@
#ifndef GUI_WIDGETS_DROPDOWN_H
#define GUI_WIDGETS_DROPDOWN_H
-#include "gui/base/basiccontainer.hpp"
+#include "gui/widgets/basiccontainer.h"
#include "listeners/actionlistener.h"
#include "listeners/focuslistener.h"
@@ -46,7 +46,7 @@ class Skin;
* your list.
*/
class DropDown final : public ActionListener,
- public gcn::BasicContainer,
+ public BasicContainer,
public KeyListener,
public MouseListener,
public FocusListener,
diff --git a/src/gui/widgets/guitable.cpp b/src/gui/widgets/guitable.cpp
index 70ebb77d6..128281fe9 100644
--- a/src/gui/widgets/guitable.cpp
+++ b/src/gui/widgets/guitable.cpp
@@ -101,7 +101,7 @@ GuiTable::GuiTable(const Widget2 *const widget,
KeyListener(),
mModel(nullptr),
mTopWidget(nullptr),
- mActionListeners(),
+ mActionListeners2(),
mHighlightColor(getThemeColor(Theme::HIGHLIGHT)),
mSelectedRow(-1),
mSelectedColumn(-1),
@@ -266,8 +266,8 @@ void GuiTable::setSelectedColumn(const int selected)
void GuiTable::uninstallActionListeners()
{
- delete_all(mActionListeners);
- mActionListeners.clear();
+ delete_all(mActionListeners2);
+ mActionListeners2.clear();
}
void GuiTable::installActionListeners()
@@ -285,7 +285,7 @@ void GuiTable::installActionListeners()
Widget *const widget = mModel->getElementAt(row, column);
if (widget)
{
- mActionListeners.push_back(new GuiTableActionListener(
+ mActionListeners2.push_back(new GuiTableActionListener(
this, widget, row, column));
}
}
diff --git a/src/gui/widgets/guitable.h b/src/gui/widgets/guitable.h
index fb0c34784..7cec854a8 100644
--- a/src/gui/widgets/guitable.h
+++ b/src/gui/widgets/guitable.h
@@ -183,7 +183,7 @@ private:
Widget *mTopWidget;
/** Vector for compactness; used as a list in practice. */
- std::vector<GuiTableActionListener *> mActionListeners;
+ std::vector<GuiTableActionListener *> mActionListeners2;
/**
* Holds the background color of the table.
diff --git a/src/gui/widgets/label.cpp b/src/gui/widgets/label.cpp
index 56c949964..b500ec7bb 100644
--- a/src/gui/widgets/label.cpp
+++ b/src/gui/widgets/label.cpp
@@ -19,6 +19,49 @@
* 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.
+ */
+
#include "gui/widgets/label.h"
#include "gui/font.h"
@@ -30,7 +73,9 @@ Skin *Label::mSkin = nullptr;
int Label::mInstances = 0;
Label::Label(const Widget2 *const widget) :
- gcn::Label(widget),
+ Widget(widget),
+ mCaption(),
+ mAlignment(Graphics::LEFT),
mPadding(0)
{
init();
@@ -38,9 +83,17 @@ Label::Label(const Widget2 *const widget) :
Label::Label(const Widget2 *const widget,
const std::string &caption) :
- gcn::Label(widget, caption),
+ Widget(widget),
+ mCaption(caption),
+ mAlignment(Graphics::LEFT),
mPadding(0)
{
+ const Font *const font = getFont();
+ if (font)
+ {
+ setWidth(font->getWidth(caption));
+ setHeight(font->getHeight());
+ }
init();
}
diff --git a/src/gui/widgets/label.h b/src/gui/widgets/label.h
index 616f6cc79..d205ed77b 100644
--- a/src/gui/widgets/label.h
+++ b/src/gui/widgets/label.h
@@ -19,10 +19,53 @@
* 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 GUI_WIDGETS_LABEL_H
#define GUI_WIDGETS_LABEL_H
-#include "gui/base/widgets/label.hpp"
+#include "gui/widgets/widget.h"
#include "localconsts.h"
@@ -34,7 +77,7 @@ class Skin;
*
* \ingroup GUI
*/
-class Label final : public gcn::Label
+class Label final : public Widget
{
public:
/**
@@ -69,11 +112,61 @@ class Label final : public gcn::Label
void resizeTo(const int maxSize, const int minSize);
+ /**
+ * Gets the caption of the label.
+ *
+ * @return The caption of the label.
+ * @see setCaption
+ */
+ const std::string &getCaption() const
+ { return mCaption; }
+
+ /**
+ * 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)
+ { mCaption = 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)
+ { mAlignment = 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
+ { return mAlignment; }
+
static Skin *mSkin;
static int mInstances;
private:
+ /**
+ * Holds the caption of the label.
+ */
+ std::string mCaption;
+
+ /**
+ * Holds the alignment of the caption.
+ */
+ Graphics::Alignment mAlignment;
+
int mPadding;
};
diff --git a/src/gui/widgets/layout.cpp b/src/gui/widgets/layout.cpp
index 24722510b..668334fd5 100644
--- a/src/gui/widgets/layout.cpp
+++ b/src/gui/widgets/layout.cpp
@@ -24,7 +24,7 @@
#include "logger.h"
-#include "gui/base/widgets/container.hpp"
+#include "gui/widgets/basiccontainer2.h"
#include <cassert>
diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h
index 288c282a0..27af0840d 100644
--- a/src/gui/widgets/layout.h
+++ b/src/gui/widgets/layout.h
@@ -27,13 +27,8 @@
#include <vector>
+class BasicContainer2;
class LayoutCell;
-
-namespace gcn
-{
- class Container;
-}
-
class Widget;
/**
@@ -42,7 +37,7 @@ class Widget;
class ContainerPlacer final
{
public:
- explicit ContainerPlacer(gcn::Container *c = nullptr,
+ explicit ContainerPlacer(BasicContainer2 *c = nullptr,
LayoutCell *lc = nullptr) :
mContainer(c), mCell(lc)
{}
@@ -66,7 +61,7 @@ class ContainerPlacer final
const int w = 1, const int h = 1);
private:
- gcn::Container *mContainer;
+ BasicContainer2 *mContainer;
LayoutCell *mCell;
};
diff --git a/src/gui/widgets/layouthelper.cpp b/src/gui/widgets/layouthelper.cpp
index c225c7543..a8cf28bea 100644
--- a/src/gui/widgets/layouthelper.cpp
+++ b/src/gui/widgets/layouthelper.cpp
@@ -22,11 +22,11 @@
#include "gui/widgets/layouthelper.h"
-#include "gui/base/widgets/container.hpp"
+#include "gui/widgets/basiccontainer2.h"
#include "debug.h"
-LayoutHelper::LayoutHelper(gcn::Container *const container) :
+LayoutHelper::LayoutHelper(BasicContainer2 *const container) :
WidgetListener(),
mLayout(),
mContainer(container)
diff --git a/src/gui/widgets/layouthelper.h b/src/gui/widgets/layouthelper.h
index 32e3d9e34..78e34f419 100644
--- a/src/gui/widgets/layouthelper.h
+++ b/src/gui/widgets/layouthelper.h
@@ -38,7 +38,7 @@ class LayoutHelper final : public WidgetListener
/**
* Constructor.
*/
- explicit LayoutHelper(gcn::Container *const container);
+ explicit LayoutHelper(BasicContainer2 *const container);
A_DELETE_COPY(LayoutHelper)
@@ -82,7 +82,7 @@ class LayoutHelper final : public WidgetListener
private:
Layout mLayout; /**< Layout handler */
- gcn::Container *mContainer; /**< Managed container */
+ BasicContainer2 *mContainer; /**< Managed container */
};
#endif // GUI_WIDGETS_LAYOUTHELPER_H
diff --git a/src/gui/widgets/listbox.cpp b/src/gui/widgets/listbox.cpp
index c6e431634..6f0c192c6 100644
--- a/src/gui/widgets/listbox.cpp
+++ b/src/gui/widgets/listbox.cpp
@@ -20,22 +20,63 @@
* 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.
+ */
+
#include "gui/widgets/listbox.h"
#include "client.h"
-#include "events/keyevent.h"
-
#include "input/keydata.h"
+#include "listeners/selectionlistener.h"
+
#include "gui/focushandler.h"
#include "gui/font.h"
#include "gui/gui.h"
#include "gui/models/listmodel.h"
-#include "render/graphics.h"
-
#include "debug.h"
float ListBox::mAlpha = 1.0;
@@ -43,7 +84,13 @@ float ListBox::mAlpha = 1.0;
ListBox::ListBox(const Widget2 *const widget,
ListModel *const listModel,
const std::string &skin) :
- gcn::ListBox(widget, listModel),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ mSelected(-1),
+ mListModel(listModel),
+ mWrappingEnabled(false),
+ mSelectionListeners(),
mHighlightColor(getThemeColor(Theme::HIGHLIGHT)),
mForegroundSelectedColor(getThemeColor(Theme::LISTBOX_SELECTED)),
mForegroundSelectedColor2(getThemeColor(Theme::LISTBOX_SELECTED_OUTLINE)),
@@ -56,6 +103,11 @@ ListBox::ListBox(const Widget2 *const widget,
mDistributeMousePressed(true),
mCenterText(false)
{
+ setWidth(100);
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+
mForegroundColor = getThemeColor(Theme::LISTBOX);
mForegroundColor2 = getThemeColor(Theme::LISTBOX_OUTLINE);
@@ -313,3 +365,59 @@ int ListBox::getSelectionByMouse(const int y) const
return -1;
return (y - mPadding) / getRowHeight();
}
+
+void ListBox::setSelected(const int selected)
+{
+ if (!mListModel)
+ {
+ mSelected = -1;
+ }
+ else
+ {
+ if (selected < 0)
+ mSelected = -1;
+ else if (selected >= mListModel->getNumberOfElements())
+ mSelected = mListModel->getNumberOfElements() - 1;
+ else
+ mSelected = selected;
+ }
+
+ Rect scroll;
+
+ if (mSelected < 0)
+ scroll.y = 0;
+ else
+ scroll.y = getRowHeight() * mSelected;
+
+ scroll.height = getRowHeight();
+ showPart(scroll);
+
+ distributeValueChangedEvent();
+}
+
+void ListBox::setListModel(ListModel *const listModel)
+{
+ mSelected = -1;
+ mListModel = listModel;
+ adjustSize();
+}
+
+void ListBox::addSelectionListener(SelectionListener *const selectionListener)
+{
+ mSelectionListeners.push_back(selectionListener);
+}
+
+void ListBox::removeSelectionListener(SelectionListener *const
+ selectionListener)
+{
+ mSelectionListeners.remove(selectionListener);
+}
+
+void ListBox::distributeValueChangedEvent()
+{
+ FOR_EACH (SelectionListenerIterator, iter, mSelectionListeners)
+ {
+ SelectionEvent event(this);
+ (*iter)->valueChanged(event);
+ }
+}
diff --git a/src/gui/widgets/listbox.h b/src/gui/widgets/listbox.h
index 64faa6eb5..f784b3237 100644
--- a/src/gui/widgets/listbox.h
+++ b/src/gui/widgets/listbox.h
@@ -20,12 +20,58 @@
* 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 GUI_WIDGETS_LISTBOX_H
#define GUI_WIDGETS_LISTBOX_H
#include "gui/color.h"
-#include "gui/base/widgets/listbox.hpp"
+#include "gui/widgets/widget.h"
+
+#include "listeners/keylistener.h"
+#include "listeners/mouselistener.h"
#include "localconsts.h"
@@ -33,6 +79,7 @@ class Skin;
class KeyEvent;
class ListModel;
class MouseEvent;
+class SelectionListener;
class Widget2;
/**
@@ -42,7 +89,9 @@ class Widget2;
*
* \ingroup GUI
*/
-class ListBox : public gcn::ListBox
+class ListBox : public Widget,
+ public MouseListener,
+ public KeyListener
{
public:
/**
@@ -103,13 +152,137 @@ class ListBox : public gcn::ListBox
int getPressedIndex() const
{ return mPressedIndex; }
- unsigned int getRowHeight() const override A_WARN_UNUSED
+ virtual unsigned int getRowHeight() const A_WARN_UNUSED
{ return mRowHeight; }
void setRowHeight(unsigned int n)
{ mRowHeight = n; }
+ /**
+ * 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
+ { return mSelected; }
+
+ /**
+ * 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(const 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() const
+ { return mListModel; }
+
+ /**
+ * 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
+ { return mWrappingEnabled; }
+
+ /**
+ * 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(const bool wrappingEnabled)
+ { mWrappingEnabled = 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 *const selectionListener);
+
+ /**
+ * Removes a selection listener from the list box.
+ *
+ * @param selectionListener The selection listener to remove.
+ * @since 0.8.0
+ */
+ void removeSelectionListener(SelectionListener *const
+ selectionListener);
+
+ /**
+ * Distributes a value changed event to all selection listeners
+ * of the list box.
+ *
+ * @since 0.8.0
+ */
+ void distributeValueChangedEvent();
+
protected:
+ /**
+ * 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;
+
Color mHighlightColor;
Color mForegroundSelectedColor;
Color mForegroundSelectedColor2;
diff --git a/src/gui/widgets/playerbox.cpp b/src/gui/widgets/playerbox.cpp
index 7ef543511..2ba452620 100644
--- a/src/gui/widgets/playerbox.cpp
+++ b/src/gui/widgets/playerbox.cpp
@@ -36,7 +36,8 @@ PlayerBox::PlayerBox(Widget2 *const widget,
Being *const being,
const std::string &skin,
const std::string &selectedSkin) :
- ScrollArea(widget),
+ Widget(widget),
+ MouseListener(),
mBeing(being),
mAlpha(1.0),
mBackground(),
@@ -54,7 +55,8 @@ PlayerBox::PlayerBox(Widget2 *const widget,
PlayerBox::PlayerBox(Widget2 *const widget,
const std::string &skin,
const std::string &selectedSkin) :
- ScrollArea(widget),
+ Widget(widget),
+ MouseListener(),
mBeing(nullptr),
mAlpha(1.0),
mBackground(),
@@ -82,6 +84,7 @@ PlayerBox::~PlayerBox()
void PlayerBox::init(std::string name, std::string selectedName)
{
setFrameSize(2);
+ addMouseListener(this);
Theme *const theme = Theme::instance();
if (theme)
@@ -153,10 +156,10 @@ void PlayerBox::drawFrame(Graphics *graphics)
void PlayerBox::mouseReleased(MouseEvent& event)
{
- ScrollArea::mouseReleased(event);
if (event.getButton() == MouseEvent::LEFT)
{
if (!mActionEventId.empty())
distributeActionEvent();
+ event.consume();
}
}
diff --git a/src/gui/widgets/playerbox.h b/src/gui/widgets/playerbox.h
index 7481dc9db..1a9067378 100644
--- a/src/gui/widgets/playerbox.h
+++ b/src/gui/widgets/playerbox.h
@@ -23,7 +23,9 @@
#ifndef GUI_WIDGETS_PLAYERBOX_H
#define GUI_WIDGETS_PLAYERBOX_H
-#include "gui/base/widgets/scrollarea.hpp"
+#include "gui/widgets/widget.h"
+
+#include "listeners/mouselistener.h"
#include "localconsts.h"
@@ -35,7 +37,8 @@ class Skin;
*
* \ingroup GUI
*/
-class PlayerBox final : public gcn::ScrollArea
+class PlayerBox final : public Widget,
+ public MouseListener
{
public:
/**
diff --git a/src/gui/widgets/radiobutton.cpp b/src/gui/widgets/radiobutton.cpp
index bb9ae46f9..411216455 100644
--- a/src/gui/widgets/radiobutton.cpp
+++ b/src/gui/widgets/radiobutton.cpp
@@ -20,12 +20,53 @@
* 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.
+ */
+
#include "gui/widgets/radiobutton.h"
#include "client.h"
-#include "events/keyevent.h"
-
#include "input/keydata.h"
#include "resources/image.h"
@@ -39,17 +80,32 @@ int RadioButton::instances = 0;
Skin *RadioButton::mSkin = nullptr;
float RadioButton::mAlpha = 1.0;
+RadioButton::GroupMap RadioButton::mGroupMap;
+
RadioButton::RadioButton(const Widget2 *const widget,
const std::string &restrict caption,
const std::string &restrict group,
const bool marked):
- gcn::RadioButton(widget, caption, group, marked),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ mSelected(false),
+ mCaption(),
+ mGroup(),
mPadding(0),
mImagePadding(0),
mImageSize(9),
mSpacing(2),
mHasMouse(false)
{
+ setCaption(caption);
+ setGroup(group);
+ setSelected(marked);
+
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+
mForegroundColor = getThemeColor(Theme::RADIOBUTTON);
mForegroundColor2 = getThemeColor(Theme::RADIOBUTTON_OUTLINE);
if (instances == 0)
@@ -77,6 +133,8 @@ RadioButton::RadioButton(const Widget2 *const widget,
RadioButton::~RadioButton()
{
+ setGroup("");
+
if (gui)
gui->removeDragged(this);
@@ -196,3 +254,57 @@ void RadioButton::adjustSize()
setWidth(mImagePadding + mImageSize + mSpacing
+ font->getWidth(mCaption) + mPadding);
}
+
+void RadioButton::setSelected(const bool selected)
+{
+ if (selected && !mGroup.empty())
+ {
+ for (GroupIterator iter = mGroupMap.lower_bound(mGroup),
+ iterEnd = mGroupMap.upper_bound(mGroup);
+ iter != iterEnd;
+ ++ iter)
+ {
+ if (iter->second && iter->second->isSelected())
+ iter->second->setSelected(false);
+ }
+ }
+
+ mSelected = selected;
+}
+
+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.empty())
+ mGroupMap.insert(std::pair<std::string, RadioButton *>(group, this));
+
+ mGroup = group;
+}
diff --git a/src/gui/widgets/radiobutton.h b/src/gui/widgets/radiobutton.h
index 2deb9a772..5aa0d9289 100644
--- a/src/gui/widgets/radiobutton.h
+++ b/src/gui/widgets/radiobutton.h
@@ -20,10 +20,56 @@
* 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 GUI_WIDGETS_RADIOBUTTON_H
#define GUI_WIDGETS_RADIOBUTTON_H
-#include "gui/base/widgets/radiobutton.hpp"
+#include "listeners/keylistener.h"
+#include "listeners/mouselistener.h"
+
+#include "gui/widgets/widget.h"
#include "localconsts.h"
@@ -32,7 +78,10 @@ class Skin;
/**
* Guichan based RadioButton with custom look
*/
-class RadioButton final : public gcn::RadioButton
+class RadioButton final : public Widget,
+ public MouseListener,
+ public KeyListener
+
{
public:
/**
@@ -53,7 +102,7 @@ class RadioButton final : public gcn::RadioButton
/**
* Draws the radiobutton, not the caption.
*/
- void drawBox(Graphics* graphics) override final;
+ void drawBox(Graphics* graphics);
/**
* Implementation of the draw methods.
@@ -77,10 +126,102 @@ class RadioButton final : public gcn::RadioButton
void adjustSize();
+ /**
+ * Checks if the radio button is selected.
+ *
+ * @return True if the radio button is selecte, false otherwise.
+ * @see setSelected
+ */
+ bool isSelected() const
+ { return mSelected; }
+
+ /**
+ * Sets the radio button to selected or not.
+ *
+ * @param selected True if the radio button should be selected,
+ * false otherwise.
+ * @see isSelected
+ */
+ void setSelected(const bool selected);
+
+ /**
+ * Gets the caption of the radio button.
+ *
+ * @return The caption of the radio button.
+ * @see setCaption
+ */
+ const std::string &getCaption() const
+ { return mCaption; }
+
+ /**
+ * 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)
+ { mCaption = caption; }
+
+ void mouseClicked(MouseEvent& mouseEvent) override final;
+
+ void mouseDragged(MouseEvent& mouseEvent) override final;
+
+ /**
+ * 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
+ { return mGroup; }
+
private:
static int instances;
static Skin *mSkin;
static float mAlpha;
+
+ /**
+ * 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;
+
int mPadding;
int mImagePadding;
int mImageSize;
diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp
index dcc3a871b..47b8b0985 100644
--- a/src/gui/widgets/scrollarea.cpp
+++ b/src/gui/widgets/scrollarea.cpp
@@ -20,6 +20,49 @@
* 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.
+ */
+
#include "gui/widgets/scrollarea.h"
#include "client.h"
@@ -53,21 +96,44 @@ ScrollArea::ScrollArea(Widget2 *const widget2,
Widget *const widget,
const bool opaque,
const std::string &skin) :
- gcn::ScrollArea(widget2, widget),
+ BasicContainer(widget2),
+ MouseListener(),
WidgetListener(),
+ mVertexes(new ImageCollection),
+ mVertexes2(new ImageCollection),
+ mHPolicy(SHOW_AUTO),
+ mVPolicy(SHOW_AUTO),
+ mVScroll(0),
+ mHScroll(0),
+ mScrollbarWidth(12),
+ mUpButtonScrollAmount(10),
+ mDownButtonScrollAmount(10),
+ mLeftButtonScrollAmount(10),
+ mRightButtonScrollAmount(10),
+ mHorizontalMarkerDragOffset(0),
+ mVerticalMarkerDragOffset(0),
mX(0),
mY(0),
mClickX(0),
mClickY(0),
- mVertexes(new ImageCollection),
- mVertexes2(new ImageCollection),
mXOffset(0),
mYOffset(0),
mDrawWidth(0),
mDrawHeight(0),
+ mVBarVisible(false),
+ mHBarVisible(false),
+ mUpButtonPressed(false),
+ mDownButtonPressed(false),
+ mLeftButtonPressed(false),
+ mRightButtonPressed(false),
+ mIsVerticalMarkerDragged(false),
+ mIsHorizontalMarkerDragged(false),
+ mOpaque(true),
mHasMouse(false),
mRedraw(true)
{
+ setContent(widget);
+ addMouseListener(this);
mOpaque = opaque;
init(skin);
}
@@ -102,6 +168,8 @@ ScrollArea::~ScrollArea()
mVertexes = nullptr;
delete mVertexes2;
mVertexes2 = nullptr;
+
+ setContent(nullptr);
}
void ScrollArea::init(std::string skinName)
@@ -178,20 +246,30 @@ void ScrollArea::logic()
return;
}
- gcn::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();
+ }
// When no scrollbar in a certain direction, adapt content size to match
// the content dimension exactly.
if (content)
{
const unsigned int frameSize = 2 * content->getFrameSize();
- if (mHPolicy == gcn::ScrollArea::SHOW_NEVER)
+ if (mHPolicy == ScrollArea::SHOW_NEVER)
{
content->setWidth((mVBarVisible ? (mDimension.width
- mScrollbarWidth) : mDimension.width) - frameSize);
}
- if (mVPolicy == gcn::ScrollArea::SHOW_NEVER)
+ if (mVPolicy == ScrollArea::SHOW_NEVER)
{
content->setHeight((mHBarVisible ? (mDimension.height
- mScrollbarWidth) : mDimension.height) - frameSize);
@@ -377,11 +455,9 @@ void ScrollArea::setOpaque(bool opaque)
setFrameSize(mOpaque ? 2 : 0);
}
-void ScrollArea::drawButton(Graphics *const graphics,
- const BUTTON_DIR dir)
+Image *ScrollArea::getImageByState(Rect &dim, const BUTTON_DIR dir)
{
int state = 0;
- Rect dim;
switch (dir)
{
@@ -405,52 +481,35 @@ void ScrollArea::drawButton(Graphics *const graphics,
default:
logger->log("ScrollArea::drawButton unknown dir: "
+ toString(static_cast<unsigned>(dir)));
- return;
+ return nullptr;
}
+ return buttons[dir][state];
+}
- if (buttons[dir][state])
- graphics->drawImage(buttons[dir][state], dim.x, dim.y);
+void ScrollArea::drawButton(Graphics *const graphics,
+ const BUTTON_DIR dir)
+{
+ Rect dim;
+ const Image *const image = getImageByState(dim, dir);
+
+ if (image)
+ graphics->drawImage(image, dim.x, dim.y);
}
void ScrollArea::calcButton(Graphics *const graphics,
const BUTTON_DIR dir)
{
- int state = 0;
Rect dim;
+ const Image *const image = getImageByState(dim, dir);
- switch (dir)
- {
- case UP:
- state = mUpButtonPressed ? 1 : 0;
- dim = getUpButtonDimension();
- break;
- case DOWN:
- state = mDownButtonPressed ? 1 : 0;
- dim = getDownButtonDimension();
- break;
- case LEFT:
- state = mLeftButtonPressed ? 1 : 0;
- dim = getLeftButtonDimension();
- break;
- case RIGHT:
- state = mRightButtonPressed ? 1 : 0;
- dim = getRightButtonDimension();
- break;
- case BUTTONS_DIR:
- default:
- logger->log("ScrollArea::drawButton unknown dir: "
- + toString(static_cast<unsigned>(dir)));
- return;
- }
-
- if (buttons[dir][state])
+ if (image)
{
static_cast<Graphics*>(graphics)->calcTileCollection(
- mVertexes, buttons[dir][state], dim.x, dim.y);
+ mVertexes, image, dim.x, dim.y);
}
}
-void ScrollArea::drawVBar(Graphics *const graphics)
+void ScrollArea::drawVBar(Graphics *const graphics) const
{
const Rect &dim = getVerticalBarDimension();
@@ -500,7 +559,7 @@ void ScrollArea::calcVBar(Graphics *const graphics)
}
}
-void ScrollArea::drawHBar(Graphics *const graphics)
+void ScrollArea::drawHBar(Graphics *const graphics) const
{
const Rect &dim = getHorizontalBarDimension();
@@ -803,7 +862,13 @@ void ScrollArea::mouseReleased(MouseEvent& event)
event.consume();
}
}
- gcn::ScrollArea::mouseReleased(event);
+ mUpButtonPressed = false;
+ mDownButtonPressed = false;
+ mLeftButtonPressed = false;
+ mRightButtonPressed = false;
+ mIsHorizontalMarkerDragged = false;
+ mIsVerticalMarkerDragged = false;
+ event.consume();
mRedraw = true;
}
@@ -1066,3 +1131,290 @@ Rect ScrollArea::getRightButtonDimension() const
mScrollbarWidth,
mScrollbarWidth);
}
+
+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(const ScrollPolicy hPolicy)
+{
+ mHPolicy = hPolicy;
+ checkPolicies();
+}
+
+void ScrollArea::setVerticalScrollPolicy(const ScrollPolicy vPolicy)
+{
+ mVPolicy = vPolicy;
+ checkPolicies();
+}
+
+void ScrollArea::setScrollPolicy(const ScrollPolicy hPolicy,
+ const ScrollPolicy vPolicy)
+{
+ mHPolicy = hPolicy;
+ mVPolicy = vPolicy;
+ checkPolicies();
+}
+
+void ScrollArea::setVerticalScrollAmount(const int vScroll)
+{
+ const int max = getVerticalMaxScroll();
+
+ mVScroll = vScroll;
+
+ if (vScroll > max)
+ mVScroll = max;
+
+ if (vScroll < 0)
+ mVScroll = 0;
+}
+
+void ScrollArea::setHorizontalScrollAmount(int hScroll)
+{
+ const int max = getHorizontalMaxScroll();
+
+ mHScroll = hScroll;
+
+ if (hScroll > max)
+ mHScroll = max;
+ else if (hScroll < 0)
+ mHScroll = 0;
+}
+
+void ScrollArea::setScrollAmount(const int hScroll, const 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(const int width)
+{
+ if (width > 0)
+ mScrollbarWidth = width;
+}
+
+void ScrollArea::showWidgetPart(Widget *const widget, Rect area)
+{
+ const Widget *const content = getContent();
+ if (widget != content)
+ return;
+
+ BasicContainer::showWidgetPart(widget, area);
+
+ setHorizontalScrollAmount(content->getFrameSize()
+ - content->getX());
+ setVerticalScrollAmount(content->getFrameSize()
+ - content->getY());
+}
+
+Rect ScrollArea::getChildrenArea()
+{
+ const Rect area = Rect(0, 0,
+ mVBarVisible ? (getWidth() - mScrollbarWidth) : getWidth(),
+ mHBarVisible ? (getHeight() - mScrollbarWidth) : getHeight());
+
+ if (area.width < 0 || area.height < 0)
+ return Rect();
+
+ return area;
+}
+
+Widget *ScrollArea::getWidgetAt(int x, int y)
+{
+ if (getChildrenArea().isPointInRect(x, y))
+ return getContent();
+
+ return nullptr;
+}
+
+void ScrollArea::setWidth(int width)
+{
+ Widget::setWidth(width);
+ checkPolicies();
+}
+
+void ScrollArea::setHeight(int height)
+{
+ Widget::setHeight(height);
+ checkPolicies();
+}
+
+void ScrollArea::setDimension(const Rect& dimension)
+{
+ Widget::setDimension(dimension);
+ checkPolicies();
+}
+
+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::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:
+ break;
+ }
+
+ 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:
+ break;
+ }
+}
diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h
index 7d2b39a96..0b0cae2c3 100644
--- a/src/gui/widgets/scrollarea.h
+++ b/src/gui/widgets/scrollarea.h
@@ -20,11 +20,55 @@
* 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 GUI_WIDGETS_SCROLLAREA_H
#define GUI_WIDGETS_SCROLLAREA_H
-#include "gui/base/widgets/scrollarea.hpp"
+#include "gui/widgets/basiccontainer.h"
+#include "listeners/mouselistener.h"
#include "listeners/widgetlistener.h"
#include "localconsts.h"
@@ -41,11 +85,28 @@ class ImageCollection;
*
* \ingroup GUI
*/
-class ScrollArea final : public gcn::ScrollArea,
+class ScrollArea final : public BasicContainer,
+ public MouseListener,
public WidgetListener
{
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.
*
* @param content the initial content to show in the scroll area
@@ -135,6 +196,234 @@ class ScrollArea final : public gcn::ScrollArea,
Rect getRightButtonDimension() const;
+ /**
+ * 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(const 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
+ { return mHPolicy; }
+
+ /**
+ * Sets the vertical scrollbar policy. See enum with policies.
+ *
+ * @param vPolicy The policy for the vertical scrollbar.
+ * @see getVerticalScrollPolicy
+ */
+ void setVerticalScrollPolicy(const ScrollPolicy vPolicy);
+
+ /**
+ * Gets the vertical scrollbar policy. See enum with policies.
+ *
+ * @return The policy for the vertical scrollbar.
+ * @see setVerticalScrollPolicy, setScrollPolicy
+ */
+ ScrollPolicy getVerticalScrollPolicy() const
+ { return mVPolicy; }
+
+ /**
+ * 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(const ScrollPolicy hPolicy,
+ const ScrollPolicy vPolicy);
+
+ /**
+ * Sets the amount to scroll vertically.
+ *
+ * @param vScroll The amount to scroll.
+ * @see getVerticalScrollAmount
+ */
+ void setVerticalScrollAmount(const int vScroll);
+
+ /**
+ * Gets the amount that is scrolled vertically.
+ *
+ * @return The scroll amount on vertical scroll.
+ * @see setVerticalScrollAmount, setScrollAmount
+ */
+ int getVerticalScrollAmount() const
+ { return mVScroll; }
+
+ /**
+ * 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
+ { return mHScroll; }
+
+ /**
+ * 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(const int hScroll, const 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(const int width);
+
+ /**
+ * Gets the width of the scroll bars.
+ *
+ * @return the width of the ScrollBar.
+ * @see setScrollbarWidth
+ */
+ int getScrollbarWidth() const
+ { return mScrollbarWidth; }
+
+ /**
+ * 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(const int amount)
+ { mLeftButtonScrollAmount = 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(const int amount)
+ { mRightButtonScrollAmount = 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(const int amount)
+ { mUpButtonScrollAmount = 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(const int amount)
+ { mDownButtonScrollAmount = 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
+ { return mLeftButtonScrollAmount; }
+
+ /**
+ * 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
+ { return mRightButtonScrollAmount; }
+
+ /**
+ * 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
+ { return mUpButtonScrollAmount; }
+
+ /**
+ * 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
+ { return mDownButtonScrollAmount; }
+
+ void showWidgetPart(Widget *const widget, Rect area) override final;
+
+ Rect getChildrenArea() override final;
+
+ Widget *getWidgetAt(int x, int y) override final;
+
+ void setWidth(int width);
+
+ void setHeight(int height);
+
+ void setDimension(const Rect& dimension);
+
+ void mouseWheelMovedUp(MouseEvent& mouseEvent) override final;
+
+ void mouseWheelMovedDown(MouseEvent& mouseEvent) override final;
+
protected:
enum BUTTON_DIR
{
@@ -150,18 +439,25 @@ class ScrollArea final : public gcn::ScrollArea,
*/
void init(std::string skinName);
+ /**
+ * Checks the policies for the scroll bars.
+ */
+ void checkPolicies();
+
void drawButton(Graphics *const graphics, const BUTTON_DIR dir);
void calcButton(Graphics *const graphics, const BUTTON_DIR dir);
- void drawVBar(Graphics *const graphics) override final;
- void drawHBar(Graphics *const graphics) override final;
- void drawVMarker(Graphics *const graphics) override final;
- void drawHMarker(Graphics *const graphics) override final;
+ void drawVBar(Graphics *const graphics) const;
+ void drawHBar(Graphics *const graphics) const;
+ void drawVMarker(Graphics *const graphics);
+ void drawHMarker(Graphics *const graphics);
void calcVBar(Graphics *const graphics);
void calcHBar(Graphics *const graphics);
void calcVMarker(Graphics *const graphics);
void calcHMarker(Graphics *const graphics);
+ Image *getImageByState(Rect &dim, const BUTTON_DIR dir);
+
void updateCalcFlag(Graphics *const graphics);
static int instances;
@@ -176,14 +472,119 @@ class ScrollArea final : public gcn::ScrollArea,
static ImageRect hBackground;
static Image *buttons[4][2];
- int mX, mY;
- int mClickX, mClickY;
ImageCollection *mVertexes;
ImageCollection *mVertexes2;
+
+ /**
+ * Holds the horizontal scroll bar policy.
+ */
+ ScrollPolicy mHPolicy;
+
+ /**
+ * Holds the vertical scroll bar policy.
+ */
+ ScrollPolicy mVPolicy;
+
+ /**
+ * 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 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;
+
+ /**
+ * Holds the horizontal markers drag offset.
+ */
+ int mHorizontalMarkerDragOffset;
+
+ /**
+ * Holds the vertical markers drag offset.
+ */
+ int mVerticalMarkerDragOffset;
+
+ int mX;
+ int mY;
+ int mClickX;
+ int mClickY;
int mXOffset;
int mYOffset;
int mDrawWidth;
int mDrawHeight;
+
+ /**
+ * 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;
+
+ /**
+ * True if the vertical marked is dragged.
+ */
+ bool mIsVerticalMarkerDragged;
+
+ /**
+ * True if the horizontal marked is dragged.
+ */
+ bool mIsHorizontalMarkerDragged;
+
+ /**
+ * True if the scroll area should be opaque (that is
+ * display its background), false otherwise.
+ */
+ bool mOpaque;
+
bool mHasMouse;
bool mRedraw;
};
diff --git a/src/gui/widgets/setupitem.cpp b/src/gui/widgets/setupitem.cpp
index 218efe8a2..4c32b0572 100644
--- a/src/gui/widgets/setupitem.cpp
+++ b/src/gui/widgets/setupitem.cpp
@@ -769,7 +769,7 @@ void SetupItemSlider::createControls()
mSlider = new Slider(this, mMin, mMax);
mSlider->setActionEventId(mEventName);
mSlider->addActionListener(mParent);
- mSlider->setValue2(atof(mValue.c_str()));
+ mSlider->setValue(atof(mValue.c_str()));
mSlider->setHeight(30);
mWidget = mSlider;
@@ -798,7 +798,7 @@ void SetupItemSlider::toWidget()
if (!mSlider)
return;
- mSlider->setValue2(atof(mValue.c_str()));
+ mSlider->setValue(atof(mValue.c_str()));
}
void SetupItemSlider::action(const ActionEvent &event A_UNUSED)
@@ -893,7 +893,7 @@ void SetupItemSlider2::createControls()
mSlider = new Slider(this, mMin, mMax);
mSlider->setActionEventId(mEventName);
mSlider->addActionListener(mParent);
- mSlider->setValue2(atof(mValue.c_str()));
+ mSlider->setValue(atof(mValue.c_str()));
mSlider->setHeight(30);
mWidget = mSlider;
@@ -952,7 +952,7 @@ void SetupItemSlider2::toWidget()
int val = roundDouble(atof(mValue.c_str()));
if (mInvert)
val = mInvertValue - val;
- mSlider->setValue2(val);
+ mSlider->setValue(val);
updateLabel();
}
diff --git a/src/gui/widgets/slider.cpp b/src/gui/widgets/slider.cpp
index 7a9b38050..700d31416 100644
--- a/src/gui/widgets/slider.cpp
+++ b/src/gui/widgets/slider.cpp
@@ -20,6 +20,49 @@
* 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.
+ */
+
#include "gui/widgets/slider.h"
#include "client.h"
@@ -47,8 +90,16 @@ static std::string const data[2] =
Slider::Slider(Widget2 *const widget,
const double scaleEnd) :
- gcn::Slider(widget, scaleEnd),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ mValue(0),
+ mStepLength(scaleEnd / 10),
+ mScaleStart(0),
+ mScaleEnd(scaleEnd),
+ mOrientation(HORIZONTAL),
mVertexes(new ImageCollection),
+ mMarkerLength(10),
mHasMouse(false),
mRedraw(true)
{
@@ -58,8 +109,16 @@ Slider::Slider(Widget2 *const widget,
Slider::Slider(Widget2 *const widget,
const double scaleStart,
const double scaleEnd) :
- gcn::Slider(widget, scaleStart, scaleEnd),
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ mValue(scaleStart),
+ mStepLength((scaleEnd - scaleStart) / 10),
+ mScaleStart(scaleStart),
+ mScaleEnd(scaleEnd),
+ mOrientation(HORIZONTAL),
mVertexes(new ImageCollection),
+ mMarkerLength(10),
mHasMouse(false),
mRedraw(true)
{
@@ -83,6 +142,12 @@ Slider::~Slider()
void Slider::init()
{
+ setFocusable(true);
+ setFrameSize(1);
+
+ addMouseListener(this);
+ addKeyListener(this);
+
setFrameSize(0);
// Load resources
@@ -289,22 +354,18 @@ void Slider::mouseExited(MouseEvent& event A_UNUSED)
void Slider::mousePressed(MouseEvent &mouseEvent)
{
+ const int x = mouseEvent.getX();
+ const int y = mouseEvent.getY();
+ const int width = mDimension.width;
+ const int height = mDimension.height;
+
if (mouseEvent.getButton() == MouseEvent::LEFT
- && mouseEvent.getX() >= 0
- && mouseEvent.getX() <= getWidth()
- && mouseEvent.getY() >= 0
- && mouseEvent.getY() <= getHeight())
+ && x >= 0 && x <= width && y >= 0 && y <= height)
{
- if (getOrientation() == HORIZONTAL)
- {
- setValue2(markerPositionToValue(
- mouseEvent.getX() - getMarkerLength() / 2));
- }
+ if (mOrientation == HORIZONTAL)
+ setValue(markerPositionToValue(x - mMarkerLength / 2));
else
- {
- setValue2(markerPositionToValue(getHeight()
- - mouseEvent.getY() - getMarkerLength() / 2));
- }
+ setValue(markerPositionToValue(height - y - mMarkerLength / 2));
distributeActionEvent();
}
@@ -312,15 +373,14 @@ void Slider::mousePressed(MouseEvent &mouseEvent)
void Slider::mouseDragged(MouseEvent &mouseEvent)
{
- if (getOrientation() == HORIZONTAL)
+ if (mOrientation == HORIZONTAL)
{
- setValue2(markerPositionToValue(mouseEvent.getX()
- - getMarkerLength() / 2));
+ setValue(markerPositionToValue(mouseEvent.getX() - mMarkerLength / 2));
}
else
{
- setValue2(markerPositionToValue(getHeight()
- - mouseEvent.getY() - getMarkerLength() / 2));
+ setValue(markerPositionToValue(
+ mDimension.height - mouseEvent.getY() - mMarkerLength / 2));
}
distributeActionEvent();
@@ -330,17 +390,15 @@ void Slider::mouseDragged(MouseEvent &mouseEvent)
void Slider::mouseWheelMovedUp(MouseEvent &mouseEvent)
{
- setValue2(getValue() + getStepLength());
+ setValue(mValue + mStepLength);
distributeActionEvent();
-
mouseEvent.consume();
}
void Slider::mouseWheelMovedDown(MouseEvent &mouseEvent)
{
- setValue2(getValue() - getStepLength());
+ setValue(mValue - mStepLength);
distributeActionEvent();
-
mouseEvent.consume();
}
@@ -348,17 +406,17 @@ void Slider::keyPressed(KeyEvent& keyEvent)
{
const int action = keyEvent.getActionId();
- if (getOrientation() == HORIZONTAL)
+ if (mOrientation == HORIZONTAL)
{
if (action == Input::KEY_GUI_RIGHT)
{
- setValue2(getValue() + getStepLength());
+ setValue(mValue + mStepLength);
distributeActionEvent();
keyEvent.consume();
}
else if (action == Input::KEY_GUI_LEFT)
{
- setValue2(getValue() - getStepLength());
+ setValue(mValue - mStepLength);
distributeActionEvent();
keyEvent.consume();
}
@@ -367,21 +425,72 @@ void Slider::keyPressed(KeyEvent& keyEvent)
{
if (action == Input::KEY_GUI_UP)
{
- setValue2(getValue() + getStepLength());
+ setValue(mValue + mStepLength);
distributeActionEvent();
keyEvent.consume();
}
else if (action == Input::KEY_GUI_DOWN)
{
- setValue2(getValue() - getStepLength());
+ setValue(mValue - mStepLength);
distributeActionEvent();
keyEvent.consume();
}
}
}
-void Slider::setValue2(const double value)
+void Slider::setScale(const double scaleStart, const double scaleEnd)
+{
+ mScaleStart = scaleStart;
+ mScaleEnd = scaleEnd;
+}
+
+void Slider::setValue(const double value)
{
- setValue(value);
mRedraw = true;
+ if (value > mScaleEnd)
+ {
+ mValue = mScaleEnd;
+ return;
+ }
+
+ if (value < mScaleStart)
+ {
+ mValue = mScaleStart;
+ return;
+ }
+
+ mValue = value;
+}
+
+double Slider::markerPositionToValue(const int v) const
+{
+ int w;
+ if (mOrientation == HORIZONTAL)
+ w = mDimension.width;
+ else
+ w = mDimension.height;
+
+ const double pos = v / (static_cast<double>(w) - mMarkerLength);
+ return (1.0 - pos) * mScaleStart + pos * mScaleEnd;
+}
+
+int Slider::valueToMarkerPosition(const double value) const
+{
+ int v;
+ if (mOrientation == HORIZONTAL)
+ v = mDimension.width;
+ else
+ v = mDimension.height;
+
+ const int w = static_cast<int>((v - mMarkerLength)
+ * (value - mScaleStart)
+ / (mScaleEnd - mScaleStart));
+
+ if (w < 0)
+ return 0;
+
+ if (w > v - mMarkerLength)
+ return v - mMarkerLength;
+
+ return w;
}
diff --git a/src/gui/widgets/slider.h b/src/gui/widgets/slider.h
index 2f21127d1..23d06de48 100644
--- a/src/gui/widgets/slider.h
+++ b/src/gui/widgets/slider.h
@@ -20,10 +20,56 @@
* 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 GUI_WIDGETS_SLIDER_H
#define GUI_WIDGETS_SLIDER_H
-#include "gui/base/widgets/slider.hpp"
+#include "listeners/keylistener.h"
+#include "listeners/mouselistener.h"
+
+#include "gui/widgets/widget.h"
#include "localconsts.h"
@@ -34,10 +80,22 @@ class ImageCollection;
*
* \ingroup GUI
*/
-class Slider final : public gcn::Slider
+class Slider final : 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 with scale start equal to 0.
*/
explicit Slider(Widget2 *const widget,
@@ -87,7 +145,125 @@ class Slider final : public gcn::Slider
void keyPressed(KeyEvent& keyEvent) override final;
- void setValue2(const double value);
+ /**
+ * 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(const double scaleStart, const double scaleEnd);
+
+ /**
+ * Gets the start value of the scale.
+ *
+ * @return The start value of the scale.
+ * @see setScaleStart, setScale
+ */
+ double getScaleStart() const
+ { return mScaleStart; }
+
+ /**
+ * Sets the start value of the scale.
+ *
+ * @param scaleStart The start value of the scale.
+ * @see getScaleStart
+ */
+ void setScaleStart(const double scaleStart)
+ { mScaleStart = scaleStart; }
+
+ /**
+ * Gets the end value of the scale.
+ *
+ * @return The end value of the scale.
+ * @see setScaleEnd, setScale
+ */
+ double getScaleEnd() const
+ { return mScaleEnd; }
+
+ /**
+ * Sets the end value of the scale.
+ *
+ * @param scaleEnd The end value of the scale.
+ * @see getScaleEnd
+ */
+ void setScaleEnd(const double scaleEnd)
+ { mScaleEnd = scaleEnd; }
+
+ /**
+ * Sets the current selected value.
+ *
+ * @param value The current selected value.
+ * @see getValue
+ */
+ void setValue(const double value);
+
+ /**
+ * Gets the current selected value.
+ *
+ * @return The current selected value.
+ * @see setValue
+ */
+ double getValue() const
+ { return mValue; }
+
+ /**
+ * Gets the length of the marker.
+ *
+ * @return The length of the marker.
+ * @see setMarkerLength
+ */
+ int getMarkerLength() const
+ { return mMarkerLength; }
+
+ /**
+ * Sets the length of the marker.
+ *
+ * @param length The length for the marker.
+ * @see getMarkerLength
+ */
+ void setMarkerLength(const int length)
+ { mMarkerLength = length; }
+
+ /**
+ * 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(const Orientation orientation)
+ { mOrientation = 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
+ { return mOrientation; }
+
+ /**
+ * 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(const double length)
+ { mStepLength = 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
+ { return mStepLength; }
enum SLIDER_ENUM
{
@@ -108,10 +284,70 @@ class Slider final : public gcn::Slider
*/
void init();
+ /**
+ * 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
+ */
+ double markerPositionToValue(const 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
+ */
+ int valueToMarkerPosition(const double value) const;
+
+ /**
+ * Gets the marker position of the current selected value.
+ *
+ * @return The marker position of the current selected value.
+ */
+ int getMarkerPosition() const
+ { return valueToMarkerPosition(getValue()); }
+
static ImageRect buttons[2];
static float mAlpha;
static int mInstances;
+
+ /**
+ * 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 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;
+
ImageCollection *mVertexes;
+
+ /**
+ * Holds the length of the marker.
+ */
+ int mMarkerLength;
+
bool mHasMouse;
bool mRedraw;
};
diff --git a/src/gui/widgets/tabbedarea.cpp b/src/gui/widgets/tabbedarea.cpp
index d2bb24720..445f17982 100644
--- a/src/gui/widgets/tabbedarea.cpp
+++ b/src/gui/widgets/tabbedarea.cpp
@@ -75,19 +75,17 @@
#include "gui/widgets/scrollarea.h"
#include "gui/widgets/tabs/tab.h"
-#include "gui/base/widgets/container.hpp"
-
#include "debug.h"
TabbedArea::TabbedArea(const Widget2 *const widget) :
ActionListener(),
- gcn::BasicContainer(widget),
+ BasicContainer(widget),
KeyListener(),
MouseListener(),
WidgetListener(),
mSelectedTab(nullptr),
- mTabContainer(new gcn::Container(widget)),
- mWidgetContainer(new gcn::Container(widget)),
+ mTabContainer(new BasicContainer2(widget)),
+ mWidgetContainer(new BasicContainer2(widget)),
mTabsToDelete(),
mTabs(),
mTabsWidth(0),
@@ -768,7 +766,7 @@ void TabbedArea::death(const Event &event)
if (tab)
removeTab(tab);
else
- gcn::BasicContainer::death(event);
+ BasicContainer::death(event);
}
void TabbedArea::selectNextTab()
diff --git a/src/gui/widgets/tabbedarea.h b/src/gui/widgets/tabbedarea.h
index dbaa4334b..0e7a032f0 100644
--- a/src/gui/widgets/tabbedarea.h
+++ b/src/gui/widgets/tabbedarea.h
@@ -70,7 +70,7 @@
#include "listeners/mouselistener.h"
#include "listeners/widgetlistener.h"
-#include "gui/base/widgets/container.hpp"
+#include "gui/widgets/basiccontainer2.h"
#include "listeners/actionlistener.h"
@@ -82,7 +82,7 @@ class Tab;
* A tabbed area, the same as the guichan tabbed area in 0.8, but extended
*/
class TabbedArea final : public ActionListener,
- public gcn::BasicContainer,
+ public BasicContainer,
public KeyListener,
public MouseListener,
public WidgetListener
@@ -251,8 +251,8 @@ class TabbedArea final : public ActionListener,
void updateTabsWidth();
Tab* mSelectedTab;
- gcn::Container* mTabContainer;
- gcn::Container* mWidgetContainer;
+ BasicContainer2* mTabContainer;
+ BasicContainer2* mWidgetContainer;
std::vector<Tab*> mTabsToDelete;
TabContainer mTabs;
diff --git a/src/gui/widgets/tabs/chattab.cpp b/src/gui/widgets/tabs/chattab.cpp
index fe979ae5a..8fe9d707b 100644
--- a/src/gui/widgets/tabs/chattab.cpp
+++ b/src/gui/widgets/tabs/chattab.cpp
@@ -72,8 +72,8 @@ ChatTab::ChatTab(const Widget2 *const widget,
mTextOutput->setLinkHandler(chatWindow->mItemLinkHandler);
mTextOutput->setAlwaysUpdate(false);
- mScrollArea->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
- gcn::ScrollArea::SHOW_ALWAYS);
+ mScrollArea->setScrollPolicy(ScrollArea::SHOW_NEVER,
+ ScrollArea::SHOW_ALWAYS);
mScrollArea->setScrollAmount(0, 1);
if (chatWindow)
diff --git a/src/gui/widgets/tabs/setup_colors.cpp b/src/gui/widgets/tabs/setup_colors.cpp
index ac6bf2837..eb7e695f4 100644
--- a/src/gui/widgets/tabs/setup_colors.cpp
+++ b/src/gui/widgets/tabs/setup_colors.cpp
@@ -84,19 +84,19 @@ Setup_Colors::Setup_Colors(const Widget2 *const widget) :
// TRANSLATORS: settings colors tab name
setName(_("Colors"));
mColorBox->addSelectionListener(this);
- mScroll->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ mScroll->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
mPreview->setOpaque(false);
// don't do anything with links
mPreview->setLinkHandler(nullptr);
mPreviewBox->setHeight(20);
- mPreviewBox->setScrollPolicy(gcn::ScrollArea::SHOW_NEVER,
- gcn::ScrollArea::SHOW_NEVER);
+ mPreviewBox->setScrollPolicy(ScrollArea::SHOW_NEVER,
+ ScrollArea::SHOW_NEVER);
mGradTypeSlider->setWidth(180);
mGradTypeSlider->setActionEventId("slider_grad");
- mGradTypeSlider->setValue2(0);
+ mGradTypeSlider->setValue(0);
mGradTypeSlider->addActionListener(this);
mGradTypeSlider->setEnabled(false);
@@ -128,7 +128,7 @@ Setup_Colors::Setup_Colors(const Widget2 *const widget) :
mGradDelayText->setEnabled(false);
mGradDelaySlider->setWidth(180);
- mGradDelaySlider->setValue2(mGradDelayText->getValue());
+ mGradDelaySlider->setValue(mGradDelayText->getValue());
mGradDelaySlider->setActionEventId("slider_graddelay");
mGradDelaySlider->addActionListener(this);
mGradDelaySlider->setEnabled(false);
@@ -139,7 +139,7 @@ Setup_Colors::Setup_Colors(const Widget2 *const widget) :
mRedText->setEnabled(false);
mRedSlider->setWidth(180);
- mRedSlider->setValue2(mRedText->getValue());
+ mRedSlider->setValue(mRedText->getValue());
mRedSlider->setActionEventId("slider_red");
mRedSlider->addActionListener(this);
mRedSlider->setEnabled(false);
@@ -150,7 +150,7 @@ Setup_Colors::Setup_Colors(const Widget2 *const widget) :
mGreenText->setEnabled(false);
mGreenSlider->setWidth(180);
- mGreenSlider->setValue2(mGreenText->getValue());
+ mGreenSlider->setValue(mGreenText->getValue());
mGreenSlider->setActionEventId("slider_green");
mGreenSlider->addActionListener(this);
mGreenSlider->setEnabled(false);
@@ -161,7 +161,7 @@ Setup_Colors::Setup_Colors(const Widget2 *const widget) :
mBlueText->setEnabled(false);
mBlueSlider->setWidth(180);
- mBlueSlider->setValue2(mBlueText->getValue());
+ mBlueSlider->setValue(mBlueText->getValue());
mBlueSlider->setActionEventId("slider_blue");
mBlueSlider->addActionListener(this);
mBlueSlider->setEnabled(false);
@@ -356,7 +356,7 @@ void Setup_Colors::valueChanged(const SelectionEvent &event A_UNUSED)
setEntry(mGreenSlider, mGreenText, col->g);
setEntry(mBlueSlider, mBlueText, col->b);
- mGradTypeSlider->setValue2(grad);
+ mGradTypeSlider->setValue(grad);
updateGradType();
mGradTypeSlider->setEnabled(true);
}
@@ -365,7 +365,7 @@ void Setup_Colors::setEntry(Slider *const s, TextField *const t,
const int value)
{
if (s)
- s->setValue2(value);
+ s->setValue(value);
if (t)
t->setText(toString(value));
}
@@ -384,7 +384,7 @@ void Setup_Colors::cancel()
userPalette->rollback();
const int type = userPalette->getColorTypeAt(mSelected);
const Color *const col = &userPalette->getColor(type);
- mGradTypeSlider->setValue2(userPalette->getGradientType(type));
+ mGradTypeSlider->setValue(userPalette->getGradientType(type));
const int delay = userPalette->getGradientDelay(type);
setEntry(mGradDelaySlider, mGradDelayText, delay);
setEntry(mRedSlider, mRedText, col->r);
diff --git a/src/gui/widgets/tabs/setup_players.cpp b/src/gui/widgets/tabs/setup_players.cpp
index 01bb60f53..b04a25e22 100644
--- a/src/gui/widgets/tabs/setup_players.cpp
+++ b/src/gui/widgets/tabs/setup_players.cpp
@@ -100,5 +100,10 @@ Setup_Players::Setup_Players(const Widget2 *const widget) :
new SetupItemCheckBox(_("Use special diagonal speed in players moving"),
"", "useDiagonalSpeed", this, "useDiagonalSpeedEvent");
+ // TRANSLATORS: settings option
+ new SetupItemCheckBox(_("Emulate right mouse button by long mouse click"
+ " (usefull for touch interfaces)"),
+ "", "longmouseclick", this, "longmouseclickEvent");
+
setDimension(Rect(0, 0, 550, 350));
}
diff --git a/src/gui/widgets/tabs/setup_relations.cpp b/src/gui/widgets/tabs/setup_relations.cpp
index 1458ecd25..ca060477f 100644
--- a/src/gui/widgets/tabs/setup_relations.cpp
+++ b/src/gui/widgets/tabs/setup_relations.cpp
@@ -221,7 +221,7 @@ Setup_Relations::Setup_Relations(const Widget2 *const widget) :
mPlayerTitleTable->setLinewiseSelection(true);
- mPlayerScrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ mPlayerScrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
mPlayerTable->setActionEventId(ACTION_TABLE);
mPlayerTable->setLinewiseSelection(true);
mPlayerTable->addActionListener(this);
diff --git a/src/gui/widgets/tabs/setup_video.cpp b/src/gui/widgets/tabs/setup_video.cpp
index f55dceaa4..416ae8c3c 100644
--- a/src/gui/widgets/tabs/setup_video.cpp
+++ b/src/gui/widgets/tabs/setup_video.cpp
@@ -227,7 +227,7 @@ Setup_Video::Setup_Video(const Widget2 *const widget) :
ScrollArea *const scrollArea = new ScrollArea(this, mModeList,
true, "setup_video_background.xml");
scrollArea->setWidth(150);
- scrollArea->setHorizontalScrollPolicy(gcn::ScrollArea::SHOW_NEVER);
+ scrollArea->setHorizontalScrollPolicy(ScrollArea::SHOW_NEVER);
mOpenGLDropDown->setSelected(renderToIndex[mOpenGLEnabled]);
@@ -241,9 +241,9 @@ Setup_Video::Setup_Video(const Widget2 *const widget) :
? toString(mAltFps) : _("None")));
mAltFpsLabel->setWidth(150);
mFpsSlider->setEnabled(mFps > 0);
- mFpsSlider->setValue2(mFps);
+ mFpsSlider->setValue(mFps);
mAltFpsSlider->setEnabled(mAltFps > 0);
- mAltFpsSlider->setValue2(mAltFps);
+ mAltFpsSlider->setValue(mAltFps);
mFpsCheckBox->setSelected(mFps > 0);
// Pre-select the current video mode.
@@ -419,9 +419,9 @@ void Setup_Video::cancel()
mOpenGLDropDown->setSelected(renderToIndex[mOpenGLEnabled]);
mCustomCursorCheckBox->setSelected(mCustomCursorEnabled);
mFpsSlider->setEnabled(mFps > 0);
- mFpsSlider->setValue2(mFps);
+ mFpsSlider->setValue(mFps);
mAltFpsSlider->setEnabled(mAltFps > 0);
- mAltFpsSlider->setValue2(mAltFps);
+ mAltFpsSlider->setValue(mAltFps);
mFpsLabel->setCaption(mFpsCheckBox->isSelected()
// TRANSLATORS: video settings label
? toString(mFps) : _("None"));
@@ -542,7 +542,7 @@ void Setup_Video::action(const ActionEvent &event)
mFpsLabel->setCaption(text);
mFpsSlider->setEnabled(mFps > 0);
- mFpsSlider->setValue2(mFps);
+ mFpsSlider->setValue(mFps);
}
else if (id == "altfpslimitslider")
{
@@ -556,7 +556,7 @@ void Setup_Video::action(const ActionEvent &event)
// TRANSLATORS: video settings label
mAltFpsLabel->setCaption(_("Alt FPS limit: ") + text);
mAltFpsSlider->setEnabled(mAltFps > 0);
- mAltFpsSlider->setValue2(mAltFps);
+ mAltFpsSlider->setValue(mAltFps);
}
else if (id == "enableresize")
{
diff --git a/src/gui/widgets/tabs/setup_visual.cpp b/src/gui/widgets/tabs/setup_visual.cpp
index 9666b224a..860b1d516 100644
--- a/src/gui/widgets/tabs/setup_visual.cpp
+++ b/src/gui/widgets/tabs/setup_visual.cpp
@@ -203,6 +203,13 @@ Setup_Visual::Setup_Visual(const Widget2 *const widget) :
new SetupItemCheckBox(_("Allow screensaver to run"),
"", "allowscreensaver", this, "allowscreensaverEvent");
+
+ // TRANSLATORS: settings group
+ new SetupItemLabel(_("Screenshots"), "", this);
+
+ new SetupItemCheckBox(_("Add water mark into screenshots"),
+ "", "addwatermark", this, "addwatermarkEvent");
+
setDimension(Rect(0, 0, 550, 350));
}
diff --git a/src/gui/widgets/tabs/tab.cpp b/src/gui/widgets/tabs/tab.cpp
index 96ae76787..ede69619e 100644
--- a/src/gui/widgets/tabs/tab.cpp
+++ b/src/gui/widgets/tabs/tab.cpp
@@ -91,7 +91,7 @@ static std::string const data[Tab::TAB_COUNT] =
Skin *Tab::tabImg[Tab::TAB_COUNT];
Tab::Tab(const Widget2 *const widget) :
- gcn::BasicContainer(widget),
+ BasicContainer(widget),
MouseListener(),
WidgetListener(),
mLabel(new Label(this)),
diff --git a/src/gui/widgets/tabs/tab.h b/src/gui/widgets/tabs/tab.h
index 1f52cde88..246d90650 100644
--- a/src/gui/widgets/tabs/tab.h
+++ b/src/gui/widgets/tabs/tab.h
@@ -66,7 +66,7 @@
#ifndef GUI_WIDGETS_TABS_TAB_H
#define GUI_WIDGETS_TABS_TAB_H
-#include "gui/base/basiccontainer.hpp"
+#include "gui/widgets/basiccontainer.h"
#include "listeners/mouselistener.h"
#include "listeners/widgetlistener.h"
@@ -81,7 +81,7 @@ class TabbedArea;
/**
* A tab, the same as the Guichan tab in 0.8, but extended
*/
-class Tab : public gcn::BasicContainer,
+class Tab : public BasicContainer,
public MouseListener,
public WidgetListener
{
diff --git a/src/gui/widgets/textbox.cpp b/src/gui/widgets/textbox.cpp
index a1ce0e61d..5f565259b 100644
--- a/src/gui/widgets/textbox.cpp
+++ b/src/gui/widgets/textbox.cpp
@@ -20,9 +20,50 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "gui/widgets/textbox.h"
+/* _______ __ __ __ ______ __ __ _______ __ __
+ * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\
+ * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / /
+ * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / /
+ * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / /
+ * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ /
+ * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/
+ *
+ * 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.
+ */
-#include "events/keyevent.h"
+#include "gui/widgets/textbox.h"
#include "input/keydata.h"
@@ -34,9 +75,23 @@
#include "debug.h"
TextBox::TextBox(const Widget2 *const widget) :
- gcn::TextBox(widget),
- mMinWidth(getWidth())
+ Widget(widget),
+ MouseListener(),
+ KeyListener(),
+ mTextRows(),
+ mCaretColumn(0),
+ mCaretRow(0),
+ mMinWidth(getWidth()),
+ mEditable(true),
+ mOpaque(true)
{
+ setText("");
+ setFocusable(true);
+
+ addMouseListener(this);
+ addKeyListener(this);
+ adjustSize();
+
mForegroundColor = getThemeColor(Theme::TEXTBOX);
setOpaque(false);
setFrameSize(0);
@@ -163,7 +218,33 @@ void TextBox::setTextWrapped(const std::string &text, const int minDimension)
mMinWidth = minWidth;
- gcn::TextBox::setText(wrappedStream.str());
+ setText(wrappedStream.str());
+}
+
+void TextBox::setText(const std::string& text)
+{
+ mCaretColumn = 0;
+ mCaretRow = 0;
+
+ mTextRows.clear();
+
+ size_t pos;
+ size_t 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::keyPressed(KeyEvent& keyEvent)
@@ -391,3 +472,156 @@ void TextBox::setForegroundColorAll(const Color &color1,
mForegroundColor = color1;
mForegroundColor2 = color2;
}
+
+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::setTextRow(const int row, const std::string& text)
+{
+ mTextRows[row] = text;
+
+ if (mCaretRow == row)
+ setCaretColumn(mCaretColumn);
+
+ adjustSize();
+}
+
+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());
+}
+
+void TextBox::setCaretRow(const 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::getCaretPosition() const
+{
+ int pos = 0, row;
+
+ for (row = 0; row < mCaretRow; row++)
+ pos += static_cast<int>(mTextRows[row].size());
+
+ return pos + mCaretColumn;
+}
+
+void TextBox::setCaretColumn(const int column)
+{
+ mCaretColumn = column;
+
+ const int sz = static_cast<int>(mTextRows[mCaretRow].size());
+ if (mCaretColumn > sz)
+ mCaretColumn = sz;
+
+ if (mCaretColumn < 0)
+ mCaretColumn = 0;
+}
+
+void TextBox::setCaretRowColumn(const int row, const int column)
+{
+ setCaretRow(row);
+ setCaretColumn(column);
+}
+
+void TextBox::scrollToCaret()
+{
+ const Font *const font = getFont();
+ Rect scroll;
+ scroll.x = font->getWidth(mTextRows[mCaretRow].substr(0, mCaretColumn));
+ scroll.y = font->getHeight() * mCaretRow;
+ scroll.width = font->getWidth(" ");
+ // add 2 for some extra space
+ scroll.height = font->getHeight() + 2;
+ showPart(scroll);
+}
+
+void TextBox::addRow(const std::string &row)
+{
+ mTextRows.push_back(row);
+ adjustSize();
+}
+
+void TextBox::mousePressed(MouseEvent& mouseEvent)
+{
+ if (mouseEvent.getButton() == MouseEvent::LEFT)
+ {
+ const int height = getFont()->getHeight();
+ if (!height)
+ return;
+
+ mCaretRow = mouseEvent.getY() / height;
+
+ 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::drawCaret(Graphics *const graphics, const int x, const int y)
+{
+ graphics->setColor(mForegroundColor);
+ graphics->drawLine(x, getFont()->getHeight() + y, x, y);
+}
+
+void TextBox::adjustSize()
+{
+ int width = 0;
+ const Font *const font = getFont();
+ for (size_t i = 0, sz = mTextRows.size(); i < sz; ++i)
+ {
+ const int w = font->getWidth(mTextRows[i]);
+ if (width < w)
+ width = w;
+ }
+
+ setWidth(width + 1);
+ setHeight(static_cast<int>(font->getHeight() * mTextRows.size()));
+}
diff --git a/src/gui/widgets/textbox.h b/src/gui/widgets/textbox.h
index 3f78fd247..e5cfbc7c9 100644
--- a/src/gui/widgets/textbox.h
+++ b/src/gui/widgets/textbox.h
@@ -20,10 +20,56 @@
* 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 GUI_WIDGETS_TEXTBOX_H
#define GUI_WIDGETS_TEXTBOX_H
-#include "gui/base/widgets/textbox.hpp"
+#include "gui/widgets/widget.h"
+
+#include "listeners/keylistener.h"
+#include "listeners/mouselistener.h"
#include "localconsts.h"
@@ -34,7 +80,9 @@
*
* \ingroup GUI
*/
-class TextBox final : public gcn::TextBox
+class TextBox final : public Widget,
+ public MouseListener,
+ public KeyListener
{
public:
/**
@@ -66,8 +114,210 @@ class TextBox final : public gcn::TextBox
void setForegroundColorAll(const Color &color1,
const Color &color2);
+ /**
+ * 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(const int row) const
+ { return mTextRows[row]; }
+
+ /**
+ * 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(const 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
+ { return static_cast<int>(mTextRows.size()); }
+
+ /**
+ * 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
+ { return mCaretRow; }
+
+ /**
+ * Sets the row where the caret should be currently located.
+ *
+ * @param The row where the caret should be currently located.
+ * @see getCaretRow
+ */
+ void setCaretRow(const 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(const 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(const int row, const int column);
+
+ /**
+ * Scrolls the text to the caret if the text box is in a scroll area.
+ *
+ * @see ScrollArea
+ */
+ void scrollToCaret();
+
+ /**
+ * Checks if the text box is editable.
+ *
+ * @return True it the text box is editable, false otherwise.
+ * @see setEditable
+ */
+ bool isEditable() const
+ { return mEditable; }
+
+ /**
+ * Sets the text box to be editable or not.
+ *
+ * @param editable True if the text box should be editable, false otherwise.
+ */
+ void setEditable(const bool editable)
+ { mEditable = editable; }
+
+ /**
+ * Adds a row of text to the end of the text.
+ *
+ * @param row The row to add.
+ */
+ 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() const
+ { return mOpaque; }
+
+ /**
+ * 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(const bool opaque)
+ { mOpaque = opaque; }
+
+ void fontChanged() override final
+ { adjustSize(); }
+
+ void mousePressed(MouseEvent& mouseEvent) override final;
+
+ void mouseDragged(MouseEvent& mouseEvent) override final;
+
private:
+ /**
+ * 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.
+ */
+ void drawCaret(Graphics *const graphics, const int x, const int y);
+
+ /**
+ * Adjusts the text box's size to fit the text.
+ */
+ 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;
+
int mMinWidth;
+
+ /**
+ * True if the text box is editable, false otherwise.
+ */
+ bool mEditable;
+
+ /**
+ * True if the text box is editable, false otherwise.
+ */
+ bool mOpaque;
};
#endif // GUI_WIDGETS_TEXTBOX_H
diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp
index 78a2826d5..7fe8c1bf3 100644
--- a/src/gui/widgets/textfield.cpp
+++ b/src/gui/widgets/textfield.cpp
@@ -20,14 +20,55 @@
* 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.
+ */
+
#include "gui/widgets/textfield.h"
#include "client.h"
#include "input/inputmanager.h"
-#include "events/keyevent.h"
-
#include "gui/font.h"
#include "gui/gui.h"
#include "gui/viewport.h"
@@ -54,9 +95,13 @@ TextField::TextField(const Widget2 *restrict const widget,
ActionListener *restrict const listener,
const std::string &restrict eventId,
const bool sendAlwaysEvents):
- gcn::TextField(widget, text),
+ Widget(widget),
FocusListener(),
- mSendAlwaysEvents(sendAlwaysEvents),
+ KeyListener(),
+ MouseListener(),
+ mText(text),
+ mCaretPosition(0),
+ mXScroll(0),
mCaretColor(&getThemeColor(Theme::CARET)),
mPopupMenu(nullptr),
mMinimum(0),
@@ -64,8 +109,14 @@ TextField::TextField(const Widget2 *restrict const widget,
mLastEventPaste(false),
mPadding(1),
mNumeric(false),
- mLoseFocusOnTab(loseFocusOnTab)
+ mLoseFocusOnTab(loseFocusOnTab),
+ mAllowSpecialActions(true),
+ mSendAlwaysEvents(sendAlwaysEvents)
{
+ setFocusable(true);
+ addMouseListener(this);
+ addKeyListener(this);
+
setFrameSize(2);
mForegroundColor = getThemeColor(Theme::TEXTFIELD);
mForegroundColor2 = getThemeColor(Theme::TEXTFIELD_OUTLINE);
@@ -271,40 +322,22 @@ void TextField::keyPressed(KeyEvent &keyEvent)
mLastEventPaste = 0;
bool consumed(false);
- handleSDLKeys(val, consumed);
-
- if (consumed)
- {
- if (mSendAlwaysEvents)
- distributeActionEvent();
-
- keyEvent.consume();
- fixScroll();
- return;
- }
#endif
- if (consumed)
+ const int action = keyEvent.getActionId();
+ if (!inputManager.isActionActive(static_cast<int>(
+ Input::KEY_GUI_CTRL)))
{
- keyEvent.consume();
+ if (!handleNormalKeys(action, consumed))
+ {
+ if (consumed)
+ keyEvent.consume();
+ return;
+ }
}
else
{
- const int action = keyEvent.getActionId();
- if (!inputManager.isActionActive(static_cast<int>(
- Input::KEY_GUI_CTRL)))
- {
- if (!handleNormalKeys(action, consumed))
- {
- if (consumed)
- keyEvent.consume();
- return;
- }
- }
- else
- {
- handleCtrlKeys(action, consumed);
- }
+ handleCtrlKeys(action, consumed);
}
if (mSendAlwaysEvents)
@@ -413,16 +446,18 @@ void TextField::handleCtrlKeys(const int action, bool &consumed)
consumed = true;
break;
}
-#ifdef USE_SDL2
case Input::KEY_GUI_B:
{
- moveCaretBack();
- consumed = true;
+ if (mAllowSpecialActions)
+ {
+ moveCaretBack();
+ consumed = true;
+ }
break;
}
- case Input::KEY_GUI_C:
+ case Input::KEY_GUI_F:
{
- handleCopy();
+ moveCaretForward();
consumed = true;
break;
}
@@ -438,118 +473,54 @@ void TextField::handleCtrlKeys(const int action, bool &consumed)
consumed = true;
break;
}
- case Input::KEY_GUI_F:
- {
- moveCaretBack();
- consumed = true;
- break;
- }
case Input::KEY_GUI_H:
{
deleteCharLeft(mText, &mCaretPosition);
consumed = true;
break;
}
- case Input::KEY_GUI_U:
- {
- caretDeleteToStart();
- consumed = true;
- break;
- }
case Input::KEY_GUI_K:
{
mText = mText.substr(0, mCaretPosition);
consumed = true;
break;
}
- case Input::KEY_GUI_V:
- {
- handlePaste();
- consumed = true;
- break;
- }
- case Input::KEY_GUI_W:
- {
- caretDeleteWord();
- consumed = true;
- break;
- }
-#endif
- default:
- break;
- }
-}
-
-#ifndef USE_SDL2
-void TextField::handleSDLKeys(const int val, bool &consumed)
-{
- switch (val)
- {
- case 2: // Ctrl+b
+ case Input::KEY_GUI_U:
{
- moveCaretBack();
+ caretDeleteToStart();
consumed = true;
break;
}
-
- case 6: // Ctrl+f
+ case Input::KEY_GUI_C:
{
- moveCaretForward();
+ handleCopy();
consumed = true;
break;
}
-
- case 4: // Ctrl+d
+ case Input::KEY_GUI_V:
{
- caretDelete();
- consumed = true;
- break;
- }
-
- case 8: // Ctrl+h
- deleteCharLeft(mText, &mCaretPosition);
- consumed = true;
- break;
-
- case 5: // Ctrl+e
- mCaretPosition = static_cast<int>(mText.size());
- consumed = true;
- break;
-
- case 11: // Ctrl+k
- mText = mText.substr(0, mCaretPosition);
- consumed = true;
- break;
-
- case 21: // Ctrl+u
- caretDeleteToStart();
- consumed = true;
- break;
-
- case 3: // Ctrl+c
- handleCopy();
- consumed = true;
- break;
-
- case 22: // Control code 22, SYNCHRONOUS IDLE, sent on Ctrl+v
+#ifdef USE_SDL2
+ handlePaste();
+#else
// hack to prevent paste key sticking
if (mLastEventPaste && mLastEventPaste > cur_time)
break;
handlePaste();
mLastEventPaste = cur_time + 2;
+#endif
consumed = true;
break;
-
- case 23: // Ctrl+w
+ }
+ case Input::KEY_GUI_W:
+ {
caretDeleteWord();
consumed = true;
break;
-
+ }
default:
break;
}
}
-#endif
void TextField::moveCaretBack()
{
@@ -751,9 +722,11 @@ void TextField::mousePressed(MouseEvent &mouseEvent)
}
}
}
- else
+ else if (mouseEvent.getButton() == MouseEvent::LEFT)
{
- gcn::TextField::mousePressed(mouseEvent);
+ mCaretPosition = getFont()->getStringIndexAt(
+ mText, mouseEvent.getX() + mXScroll);
+ fixScroll();
}
}
@@ -768,3 +741,16 @@ void TextField::focusGained(const Event &event A_UNUSED)
void TextField::focusLost(const Event &event A_UNUSED)
{
}
+
+void TextField::setText(const std::string& text)
+{
+ const size_t sz = text.size();
+ if (sz < mCaretPosition)
+ mCaretPosition = sz;
+ mText = text;
+}
+
+void TextField::mouseDragged(MouseEvent& mouseEvent)
+{
+ mouseEvent.consume();
+}
diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h
index ccc1b16d6..93ae155be 100644
--- a/src/gui/widgets/textfield.h
+++ b/src/gui/widgets/textfield.h
@@ -20,12 +20,57 @@
* 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 GUI_WIDGETS_TEXTFIELD_H
#define GUI_WIDGETS_TEXTFIELD_H
#include "listeners/focuslistener.h"
+#include "listeners/keylistener.h"
+#include "listeners/mouselistener.h"
-#include "gui/base/widgets/textfield.hpp"
+#include "gui/widgets/widget.h"
#include "localconsts.h"
@@ -36,8 +81,10 @@ class PopupMenu;
*
* \ingroup GUI
*/
-class TextField : public gcn::TextField,
- public FocusListener
+class TextField : public Widget,
+ public FocusListener,
+ public KeyListener,
+ public MouseListener
{
public:
/**
@@ -139,26 +186,71 @@ class TextField : public gcn::TextField,
void caretDeleteWord();
+ void setAllowSpecialActions(const bool b)
+ { mAllowSpecialActions = b; }
+
+ std::string getTextBeforeCaret() const
+ { return mText.substr(0, mCaretPosition); }
+
+ /**
+ * 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
+ { return mText; }
+
+ /**
+ * 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
+ { return mCaretPosition; }
+
+ void mouseDragged(MouseEvent& mouseEvent) override final;
+
protected:
- void drawCaret(Graphics* graphics, int x) override final;
+ void drawCaret(Graphics* graphics, int x);
void fixScroll();
void fontChanged();
- bool mSendAlwaysEvents;
-
bool handleNormalKeys(const int action, bool &consumed);
void handleCtrlKeys(const int action, bool &consumed);
-#ifndef USE_SDL2
- void handleSDLKeys(const int val, bool &consumed);
-#endif
-
static Skin *mSkin;
- private:
+ /**
+ * 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;
+
const Color *mCaretColor;
PopupMenu *mPopupMenu;
static int instances;
@@ -170,6 +262,8 @@ class TextField : public gcn::TextField,
int mPadding;
bool mNumeric;
bool mLoseFocusOnTab;
+ bool mAllowSpecialActions;
+ bool mSendAlwaysEvents;
};
#endif // GUI_WIDGETS_TEXTFIELD_H
diff --git a/src/gui/widgets/widget.h b/src/gui/widgets/widget.h
index 17f016c76..3af00d247 100644
--- a/src/gui/widgets/widget.h
+++ b/src/gui/widgets/widget.h
@@ -196,7 +196,7 @@ class Widget : public Widget2
* has no parent.
* @since 0.1.0
*/
- virtual Widget* getParent() const A_WARN_UNUSED
+ Widget* getParent() const A_WARN_UNUSED
{ return mParent; }
/**
@@ -959,7 +959,7 @@ class Widget : public Widget2
* @param area The area to show.
* @since 0.1.0
*/
- virtual void showWidgetPart(Widget* widget A_UNUSED,
+ virtual void showWidgetPart(Widget *const widget A_UNUSED,
Rect area A_UNUSED)
{ }
diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp
index ec83af9a8..5a636013b 100644
--- a/src/gui/widgets/window.cpp
+++ b/src/gui/widgets/window.cpp
@@ -91,7 +91,7 @@ int Window::mouseResize = 0;
Window::Window(const std::string &caption, const bool modal,
Window *const parent, std::string skin) :
- gcn::Container(nullptr),
+ BasicContainer2(nullptr),
MouseListener(),
WidgetListener(),
mCaption(caption),
@@ -668,9 +668,9 @@ void Window::setVisible(const bool visible, const bool forceSticky)
mResizeHandles = 0;
if (mStickyButtonLock)
- gcn::Container::setVisible(visible);
+ BasicContainer2::setVisible(visible);
else
- gcn::Container::setVisible((!forceSticky && mSticky) || visible);
+ BasicContainer2::setVisible((!forceSticky && mSticky) || visible);
if (visible)
{
if (mPlayVisibleSound)
diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h
index 6369990bb..2c4ee5e5f 100644
--- a/src/gui/widgets/window.h
+++ b/src/gui/widgets/window.h
@@ -71,7 +71,7 @@
#include "listeners/mouselistener.h"
#include "listeners/widgetlistener.h"
-#include "gui/base/widgets/container.hpp"
+#include "gui/widgets/basiccontainer2.h"
#include "localconsts.h"
@@ -88,7 +88,7 @@ class WindowContainer;
*
* \ingroup GUI
*/
-class Window : public gcn::Container,
+class Window : public BasicContainer2,
public MouseListener,
private WidgetListener
{
@@ -498,7 +498,7 @@ class Window : public gcn::Container,
* @return The title bar height.
* @see setTitleBarHeight
*/
- unsigned int getTitleBarHeight()
+ unsigned int getTitleBarHeight() const
{ return mTitleBarHeight; }
/**