src/gui/list_box.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Listbox
00020  *****************************************************************************/
00021 
00022 #include "list_box.h"
00023 #include <algorithm>
00024 #include <SDL_gfxPrimitives.h>
00025 #include "../graphic/font.h"
00026 #include "../include/app.h"
00027 #include "../tool/math_tools.h"
00028 #include "../tool/resource_manager.h"
00029 
00030 //#define SCROLLBAR
00031 
00032 ListBoxItem::ListBoxItem(const std::string& _label, 
00033                          Font& _font,
00034                          const std::string& _value,
00035                          bool _enabled) : 
00036   Label(_label, Rectanglei(0,0,0,0), _font)
00037 {
00038   value = _value;
00039   enabled = _enabled;
00040 }
00041 
00042 const std::string& ListBoxItem::GetLabel() const
00043 {
00044   return txt_label->GetText();
00045 }
00046 
00047 const std::string& ListBoxItem::GetValue() const
00048 {
00049   return value;
00050 }
00051 
00052 const bool ListBoxItem::IsEnabled() const
00053 {
00054   return enabled;
00055 }
00056 
00057 // struct CompareItems
00058 // {
00059 //      bool operator()(const ListBoxItem& a, const ListBoxItem& b)
00060 //      {
00061 //        return a.GetLabel() < b.GetLabel();
00062 //      }
00063 // };
00064 
00065 ListBox::ListBox (const Rectanglei &rect, bool always_one_selected_b) : Widget(rect)
00066 {
00067   Rectanglei buttonRect;
00068   Profile *res = resource_manager.LoadXMLProfile( "graphism.xml", false);
00069 
00070   buttonRect.SetPosition(GetPositionX() + GetSizeX() - 12, GetPositionY() + 2);
00071   buttonRect.SetSize(10, 5);
00072   m_up = new Button(buttonRect, res, "menu/up");
00073   buttonRect.SetPosition(GetPositionX() + GetSizeX() - 12, GetPositionY() + GetSizeY() - 7);
00074   m_down = new Button(buttonRect, res, "menu/down");
00075 
00076   resource_manager.UnLoadXMLProfile( res);
00077 
00078   height_item = (*Font::GetInstance(Font::FONT_SMALL)).GetHeight();
00079   first_visible_item = 0;
00080   nb_visible_items_max = GetSizeY()/height_item;
00081   nb_visible_items = 0;
00082 
00083   selected_item = -1;
00084   always_one_selected = always_one_selected_b;
00085 }
00086 
00087 ListBox::~ListBox()
00088 {
00089    delete m_up;
00090    delete m_down;
00091 
00092    m_items.clear();
00093 }
00094 
00095 int ListBox::MouseIsOnWhichItem(const Point2i &mousePosition) const
00096 {
00097   if( !Contains(mousePosition) )
00098     return -1;
00099 
00100   int index = (mousePosition.y - position.y) / height_item;
00101   return BorneLong(index + first_visible_item, 0, m_items.size() - 1);
00102 }
00103 
00104 Widget* ListBox::Clic(const Point2i &mousePosition, uint button)
00105 {
00106   need_redrawing = true;
00107 
00108   // buttons for listbox with more items than visible
00109   if( m_items.size() > nb_visible_items_max ){
00110     if( (button == SDL_BUTTON_WHEELDOWN && Contains(mousePosition)) ||
00111         (button == SDL_BUTTON_LEFT && m_down->Contains(mousePosition)) ){
00112 
00113       // bottom button
00114       if( m_items.size() - first_visible_item > nb_visible_items_max )
00115         first_visible_item++ ;
00116 
00117       return this;
00118     }
00119     else if( (button == SDL_BUTTON_WHEELUP && Contains(mousePosition)) ||
00120              (button == SDL_BUTTON_LEFT && m_up->Contains(mousePosition)) ){
00121 
00122       // top button
00123       if( first_visible_item > 0 )
00124         first_visible_item-- ;
00125 
00126       return this;
00127     }
00128   }
00129 
00130   if( button == SDL_BUTTON_LEFT ){
00131     int item = MouseIsOnWhichItem(mousePosition);
00132 
00133     if( item == -1 )
00134       return NULL;
00135 
00136     if( item == selected_item ){
00137         //Deselect ();
00138     } else
00139       Select (item);
00140     return this;
00141   }
00142   else{
00143     return NULL;
00144   }
00145 }
00146 
00147 void ListBox::Draw(const Point2i &mousePosition, Surface& surf) const
00148 {
00149   int item = MouseIsOnWhichItem(mousePosition);
00150   Rectanglei rect (*this);
00151 
00152   // Draw border and bg color
00153   surf.BoxColor(rect, defaultListColor1);
00154   surf.RectangleColor(rect, white_color);
00155 
00156   // Draw items
00157   for(uint i=0; i < nb_visible_items; i++){
00158     Rectanglei rect(GetPositionX() + 1, 
00159                     GetPositionY() + i * height_item + 1, 
00160                     GetSizeX() - 2, 
00161                     height_item - 2);
00162     
00163     // item is selected or mouse-overed
00164     if( int(i + first_visible_item) == selected_item) {
00165       surf.BoxColor(rect, defaultListColor2);
00166     } else if( i + first_visible_item == uint(item) ) {
00167       surf.BoxColor(rect, defaultListColor3);
00168     }
00169 
00170     // Really draw items
00171     Point2i pos = GetPosition() + Point2i(5, i*height_item);
00172     Rectanglei rect2(pos.x, pos.y, GetSizeX()-2, height_item-2);
00173     m_items[i + first_visible_item]->SetSizePosition(rect2);
00174     //    m_items[i + first_visible_item].Draw(GetPosition() + Point2i(5, i*height_item),
00175     //                           mousePosition, surf);
00176     m_items[i + first_visible_item]->Draw(mousePosition, surf);
00177     
00178     // item is disabled
00179     if(!m_items[i]->IsEnabled())
00180       surf.BoxColor(rect, defaultDisabledColorBox);
00181   }
00182 
00183   // buttons for listbox with more items than visible
00184   if (m_items.size() > nb_visible_items_max){
00185     m_up->Draw(mousePosition, surf);
00186     m_down->Draw(mousePosition, surf);
00187 #ifdef SCROLLBAR
00188     uint tmp_y, tmp_h;
00189     tmp_y = y+10+ first_visible_item* (h-20) / m_items.size();
00190     tmp_h = nb_visible_items_max * (h-20) / m_items.size();
00191     if (tmp_h < 5) tmp_h =5;
00192 
00193     boxRGBA(surf,
00194             x+w-10, tmp_y,
00195             x+w-1,  tmp_y+tmp_h,
00196             white_color);
00197 #endif
00198   }
00199 }
00200 
00201 void ListBox::SetSizePosition(const Rectanglei &rect)
00202 {
00203   StdSetSizePosition(rect);
00204   m_up->SetSizePosition( Rectanglei(GetPositionX() + GetSizeX() - 12, GetPositionY()+2, 10, 5) );
00205   m_down->SetSizePosition( Rectanglei(GetPositionX() + GetSizeX() - 12, GetPositionY() + GetSizeY() - 7, 10, 5) );
00206 
00207   nb_visible_items_max = GetSizeY()/height_item;
00208 }
00209 
00210 void ListBox::AddItem (bool selected,
00211                        const std::string &label,
00212                        const std::string &value,
00213                        bool enabled)
00214 {
00215   uint pos = m_items.size();
00216 
00217   // Push item
00218   ListBoxItem * item = new ListBoxItem(label, *Font::GetInstance(Font::FONT_SMALL), value, enabled);
00219   m_items.push_back (item);
00220 
00221   // Select it if selected
00222   if( selected )
00223     Select (pos);
00224 
00225   nb_visible_items = m_items.size();
00226   if( nb_visible_items_max < nb_visible_items )
00227     nb_visible_items = nb_visible_items_max;
00228 }
00229 
00230 void ListBox::Sort()
00231 {
00232   //std::sort( m_items.begin(), m_items.end(), CompareItems() );
00233 }
00234 
00235 void ListBox::RemoveSelected()
00236 {
00237   assert (always_one_selected == false);
00238 
00239   if( selected_item != -1 ){
00240     m_items.erase( m_items.begin() + selected_item );
00241     selected_item =- 1;
00242   }
00243 
00244   nb_visible_items = m_items.size();
00245   if( nb_visible_items_max < nb_visible_items )
00246     nb_visible_items = nb_visible_items_max;
00247 }
00248 
00249 void ListBox::Select (uint index)
00250 {
00251   assert(index < m_items.size());
00252   selected_item = index;
00253 }
00254 
00255 void ListBox::Select(const std::string& val)
00256 {
00257   uint index = 0;
00258   for(std::vector<ListBoxItem*>::iterator it=m_items.begin();
00259       it != m_items.end();
00260       it++,index++)
00261   {
00262     if((*it)->GetLabel() == val)
00263     {
00264       Select(index);
00265       return;
00266     }
00267   }
00268 }
00269 
00270 void ListBox::Deselect ()
00271 {
00272   assert (always_one_selected == false);
00273   selected_item = -1;
00274 }
00275 
00276 int ListBox::GetSelectedItem () const
00277 {
00278   return selected_item;
00279 }
00280 
00281 const std::string& ListBox::ReadLabel () const
00282 {
00283   assert (selected_item != -1);
00284   return m_items.at(selected_item)->GetLabel();
00285 }
00286 
00287 const std::string& ListBox::ReadValue () const
00288 {
00289   assert (selected_item != -1);
00290   return m_items.at(selected_item)->GetValue();
00291 }
00292 
00293 const std::string& ListBox::ReadValue (int index) const
00294 {
00295   assert (index != -1 && index < (int)m_items.size());
00296   return m_items.at(index)->GetValue();
00297 }
00298 
00299 uint ListBox::Size() const
00300 {
00301   return m_items.size();
00302 }

Generated on Mon Jan 1 13:10:57 2007 for Wormux by  doxygen 1.4.7