togglebutton.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 /***************************************************************************
00022  * Note! Group and groupmap borrows heavily from ideas of Guichan library  *
00023  * version 0.8.1                                                           *
00024  ***************************************************************************/
00025 
00026 
00027 
00028 // Standard C++ library includes
00029 #include <cassert>
00030 #include <iostream>
00031 
00032 // 3rd party library includes
00033 #include <guichan/mouseevent.hpp>
00034 
00035 // FIFE includes
00036 // These includes are split up in two parts, separated by one empty line
00037 // First block: files included from the FIFE root src directory
00038 // Second block: files included from the same folder
00039 #include "util/log/logger.h"
00040 
00041 #include "togglebutton.h"
00042 
00043 namespace gcn {
00044     static FIFE::Logger _log(LM_GUI);
00045 
00046     ToggleButton::GroupMap ToggleButton::m_groupMap;
00047 
00048     ToggleButton::ToggleButton(Image *up_file , Image *down_file, Image *hover_file, const std::string& caption, const std::string& group):
00049         Button(),
00050         m_upImage(up_file),
00051         m_downImage(down_file),
00052         m_hoverImage(hover_file),
00053         x_downoffset(0),
00054         y_downoffset(0),
00055         m_group(group) {
00056 
00057         m_hoverImage = hover_file;
00058         setFrameSize(0);
00059         setGroup(m_group);
00060         adjustSize();
00061         mCaption = caption;
00062         m_toggled = false;
00063 
00064         addActionListener(this);
00065     }
00066 
00067     ToggleButton::~ToggleButton() {
00068         setGroup(""); // Remove button from group
00069     }
00070 
00071     void ToggleButton::setDownOffset(int32_t x, int32_t y) {
00072         x_downoffset = x;
00073         y_downoffset = y;
00074     }
00075 
00076     void ToggleButton::draw(Graphics *graphics) {
00077         Color faceColor = getBaseColor();
00078         Color highlightColor;
00079         Color shadowColor;
00080         int32_t alpha = getBaseColor().a;
00081 
00082         Image* img = NULL;
00083         int32_t xoffset = 0;
00084         int32_t yoffset = 0;
00085 
00086         if (isPressed() || m_toggled) {
00087             faceColor = faceColor - 0x303030;
00088             faceColor.a = alpha;
00089             highlightColor = faceColor - 0x303030;
00090             highlightColor.a = alpha;
00091             shadowColor = faceColor + 0x303030;
00092             shadowColor.a = alpha;
00093 
00094             if( m_downImage ) {
00095                 img = m_downImage;
00096                 xoffset = x_downoffset;
00097                 yoffset = y_downoffset;
00098             }
00099         } else if(mHasMouse) {
00100             faceColor = faceColor + 0x303030;
00101             faceColor.a = alpha;
00102             highlightColor = faceColor + 0x303030;
00103             highlightColor.a = alpha;
00104             shadowColor = faceColor - 0x303030;
00105             shadowColor.a = alpha;
00106 
00107             if ( m_hoverImage ) {
00108                 img = m_hoverImage;
00109             }
00110         } else{
00111             highlightColor = faceColor + 0x303030;
00112             highlightColor.a = alpha;
00113             shadowColor = faceColor - 0x303030;
00114             shadowColor.a = alpha;
00115 
00116             if (m_upImage) {
00117                 img = m_upImage;
00118             }
00119         }
00120 
00121 
00122         graphics->setColor(faceColor);
00123         graphics->fillRectangle(Rectangle(1, 1, getDimension().width-1, getHeight() - 1));
00124 
00125         graphics->setColor(highlightColor);
00126         graphics->drawLine(0, 0, getWidth() - 1, 0);
00127         graphics->drawLine(0, 1, 0, getHeight() - 1);
00128 
00129         graphics->setColor(shadowColor);
00130         graphics->drawLine(getWidth() - 1, 1, getWidth() - 1, getHeight() - 1);
00131         graphics->drawLine(1, getHeight() - 1, getWidth() - 1, getHeight() - 1);
00132 
00133         graphics->setColor(getForegroundColor());
00134 
00135         if (img) {
00136             graphics->drawImage(img, xoffset, yoffset);
00137         }
00138 
00139         int32_t textX;
00140         int32_t textY = getHeight() / 2 - getFont()->getHeight() / 2;
00141         switch (getAlignment())
00142         {
00143             case Graphics::LEFT:
00144                 textX = 4;
00145                 break;
00146             case Graphics::CENTER:
00147                 textX = getWidth() / 2;
00148                 break;
00149             case Graphics::RIGHT:
00150                 textX = getWidth() - 4;
00151                 break;
00152             default:
00153                 //use the default of Graphics::LEFT
00154                 textX = 4;
00155                 FL_WARN(_log, FIFE::LMsg("ToggleButton::draw() - ") << "Unknown alignment: "
00156                               << getAlignment() << ".  Using the default of Graphics::LEFT");
00157         }
00158 
00159         graphics->setFont(getFont());
00160         if (mCaption.size() > 0) {
00161             if (isPressed())
00162                 graphics->drawText(getCaption(), textX + 1,
00163                         textY + 1, getAlignment());
00164             else
00165                 graphics->drawText(getCaption(), textX, textY, getAlignment());
00166         }
00167     }
00168 
00169     void ToggleButton::action(const ActionEvent& actionEvent) {
00170         setToggled(!m_toggled);
00171     }
00172 
00173     void ToggleButton::adjustSize() {
00174         int32_t w = 0;
00175         int32_t h = w;
00176         if( m_upImage ) {
00177             w = m_upImage->getWidth();
00178             h = m_upImage->getHeight();
00179         }
00180         if( m_downImage ) {
00181             w = std::max(m_downImage->getWidth(), w);
00182             h = std::max(m_downImage->getHeight(), h);
00183         }
00184         if( m_hoverImage ) {
00185             w = std::max(m_hoverImage->getWidth(), w);
00186             h = std::max(m_hoverImage->getHeight(), h);
00187         }
00188 
00189         if( mCaption.length() > 0 ) {
00190             w = std::max(static_cast<int32_t>(getFont()->getWidth(mCaption)+2*mSpacing), w);
00191             h = std::max(static_cast<int32_t>(getFont()->getHeight()+2*mSpacing), h);
00192         }
00193 
00194         setWidth(w);
00195         setHeight(h);
00196     }
00197 
00198     void ToggleButton::setUpImage(Image* image) {
00199         m_upImage = image;
00200         adjustSize();
00201     }
00202 
00203     void ToggleButton::setDownImage(Image* image) {
00204         m_downImage = image;
00205         adjustSize();
00206     }
00207 
00208     void ToggleButton::setHoverImage(Image* image) {
00209         m_hoverImage = image;
00210         adjustSize();
00211     }
00212 
00213     bool ToggleButton::isToggled() const {
00214         return m_toggled;
00215     }
00216 
00217     void ToggleButton::setToggled(bool toggled) {
00218         if (toggled && m_group != "") {
00219             // untoggle all buttons in group
00220             GroupIterator iter, iterEnd;
00221             iterEnd = m_groupMap.upper_bound(m_group);
00222 
00223             for (iter = m_groupMap.lower_bound(m_group); iter != iterEnd; iter++) {
00224                 if (iter->second->isToggled()) {
00225                     iter->second->setToggled(false);
00226                 }
00227             }
00228         }
00229 
00230         m_toggled = toggled;
00231     }
00232 
00233     void ToggleButton::setGroup(const std::string &group) {
00234         // Remove button from previous group
00235         if (m_group != "") {
00236             GroupIterator iter, iterEnd;
00237             iterEnd = m_groupMap.upper_bound(m_group);
00238 
00239             for (iter = m_groupMap.lower_bound(m_group); iter != iterEnd; iter++) {
00240                 if (iter->second == this) {
00241                     m_groupMap.erase(iter);
00242                     break;
00243                 }
00244             }
00245         }
00246 
00247         // Add button to new group
00248         if (group != "") {
00249             m_groupMap.insert( std::pair<std::string, ToggleButton *>(group, this));
00250         }
00251 
00252         m_group = group;
00253     }
00254 
00255     const std::string &ToggleButton::getGroup() const {
00256         return m_group;
00257     }
00258 
00259     int32_t ToggleButton::getDownXOffset() const {
00260         return x_downoffset;
00261     }
00262 
00263     int32_t ToggleButton::getDownYOffset() const {
00264         return y_downoffset;
00265     }
00266 
00267 }
00268 /* vim: set noexpandtab: set shiftwidth=2: set tabstop=2: */
00269