diff options
Diffstat (limited to 'src/guichan/widgets/radiobutton.cpp')
-rw-r--r-- | src/guichan/widgets/radiobutton.cpp | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/src/guichan/widgets/radiobutton.cpp b/src/guichan/widgets/radiobutton.cpp new file mode 100644 index 000000000..31fdec94d --- /dev/null +++ b/src/guichan/widgets/radiobutton.cpp @@ -0,0 +1,298 @@ +/* _______ __ __ __ ______ __ __ _______ __ __ + * / _____/\ / /\ / /\ / /\ / ____/\ / /\ / /\ / ___ /\ / |\/ /\ + * / /\____\// / // / // / // /\___\// /_// / // /\_/ / // , |/ / / + * / / /__ / / // / // / // / / / ___ / // ___ / // /| ' / / + * / /_// /\ / /_// / // / // /_/_ / / // / // /\_/ / // / | / / + * /______/ //______/ //_/ //_____/\ /_/ //_/ //_/ //_/ //_/ /|_/ / + * \______\/ \______\/ \_\/ \_____\/ \_\/ \_\/ \_\/ \_\/ \_\/ \_\/ + * + * 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 "guichan/widgets/radiobutton.hpp" + +#include "guichan/font.hpp" +#include "guichan/graphics.hpp" +#include "guichan/key.hpp" +#include "guichan/mouseinput.hpp" + +namespace gcn +{ + RadioButton::GroupMap RadioButton::mGroupMap; + + RadioButton::RadioButton() + { + setSelected(false); + + setFocusable(true); + addMouseListener(this); + addKeyListener(this); + } + + RadioButton::RadioButton(const std::string &caption, + const std::string &group, + bool selected) + { + setCaption(caption); + setGroup(group); + setSelected(selected); + + setFocusable(true); + addMouseListener(this); + addKeyListener(this); + + adjustSize(); + } + + RadioButton::~RadioButton() + { + // Remove us from the group list + setGroup(""); + } + + void RadioButton::draw(Graphics* graphics) + { + graphics->pushClipArea(Rectangle(1, + 1, + getWidth() - 1, + getHeight() - 1)); + drawBox(graphics); + graphics->popClipArea(); + + + graphics->setFont(getFont()); + graphics->setColor(getForegroundColor()); + + if (isFocused()) + { + int fh; + + if (getHeight()%2 == 0) + { + fh = getHeight() - 4; + } + else + { + fh = getHeight() - 3; + } + + int hh = (fh + 1) / 2; + + graphics->drawLine(0, hh + 1, hh + 1, 0); + graphics->drawLine(hh + 2, 1, fh + 2, hh + 1); + graphics->drawLine(fh + 1, hh + 2, hh + 1, fh + 2); + graphics->drawLine(hh + 1, fh + 2, 1, hh + 2); + } + + int h = getHeight() + getHeight() / 2; + + graphics->drawText(getCaption(), h - 2, 0); + } + + void RadioButton::drawBox(Graphics *graphics) + { + int h; + + if (getHeight()%2 == 0) + { + h = getHeight() - 4; + } + else + { + h = getHeight() - 3; + } + + int alpha = getBaseColor().a; + Color faceColor = getBaseColor(); + faceColor.a = alpha; + Color highlightColor = faceColor + 0x303030; + highlightColor.a = alpha; + Color shadowColor = faceColor - 0x303030; + shadowColor.a = alpha; + + graphics->setColor(getBackgroundColor()); + + int i; + int hh = (h + 1) / 2; + + for (i = 1; i <= hh; ++i) + { + graphics->drawLine(hh - i + 1, + i, + hh + i - 1, + i); + } + + for (i = 1; i < hh; ++i) + { + graphics->drawLine(hh - i + 1, + h - i, + hh + i - 1, + h - i); + } + + graphics->setColor(shadowColor); + graphics->drawLine(hh, 0, 0, hh); + graphics->drawLine(hh + 1, 1, h - 1, hh - 1); + + graphics->setColor(highlightColor); + graphics->drawLine(1, hh + 1, hh, h); + graphics->drawLine(hh + 1, h - 1, h, hh); + + graphics->setColor(getForegroundColor()); + + int hhh = hh - 3; + if (mSelected) + { + for (i = 0; i < hhh; ++i) + { + graphics->drawLine(hh - i, 4 + i, hh + i, 4 + i); + } + for (i = 0; i < hhh; ++i) + { + graphics->drawLine(hh - i, h - 4 - i, hh + i, h - 4 - i); + } + + } + } + + bool RadioButton::isSelected() const + { + return mSelected; + } + + void RadioButton::setSelected(bool selected) + { + if (selected && mGroup != "") + { + GroupIterator iter, iterEnd; + iterEnd = mGroupMap.upper_bound(mGroup); + + for (iter = mGroupMap.lower_bound(mGroup); + iter != iterEnd; + iter++) + { + if (iter->second->isSelected()) + { + iter->second->setSelected(false); + } + } + } + + mSelected = selected; + } + + const std::string &RadioButton::getCaption() const + { + return mCaption; + } + + void RadioButton::setCaption(const std::string caption) + { + mCaption = caption; + } + + void RadioButton::keyPressed(KeyEvent& keyEvent) + { + Key key = keyEvent.getKey(); + + if (key.getValue() == Key::ENTER || + key.getValue() == Key::SPACE) + { + setSelected(true); + distributeActionEvent(); + keyEvent.consume(); + } + } + + 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 != "") + { + GroupIterator iter, iterEnd; + iterEnd = mGroupMap.upper_bound(mGroup); + + for (iter = mGroupMap.lower_bound(mGroup); + iter != iterEnd; + iter++) + { + if (iter->second == this) + { + mGroupMap.erase(iter); + break; + } + } + } + + if (group != "") + { + mGroupMap.insert( + std::pair<std::string, RadioButton *>(group, this)); + } + + mGroup = group; + } + + const std::string &RadioButton::getGroup() const + { + return mGroup; + } + + void RadioButton::adjustSize() + { + int height = getFont()->getHeight(); + + setHeight(height); + setWidth(getFont()->getWidth(getCaption()) + height + height/2); + } +} |