Back to index

extremetuxracer  0.5beta
listbox.cpp
Go to the documentation of this file.
00001 /* 
00002  * PPRacer 
00003  * Copyright (C) 2004-2005 Volker Stroebel <volker@planetpenguin.de>
00004  *
00005  * Copyright (C) 1999-2001 Jasmin F. Patry
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00020  */
00021 
00022 
00023 #include "ui_theme.h"
00024 #include "ui_mgr.h"
00025 
00026 #define DEFAULT_ARROW_BUTTON_HEIGHT 15
00027 #define DEFAULT_ARROW_BUTTON_WIDTH  27
00028 #define DEFAULT_ARROW_REGION_WIDTH  36
00029 #define DEFAULT_ARROW_VERT_SEPARATION  4
00030 #define DEFAULT_BORDER_WIDTH 4
00031 #define LDEFAULT_TEXT_PAD 8
00032 
00033 
00034 namespace pp{
00035 
00036 template <class T>
00037 Listbox<T>::Listbox(  pp::Vec2d pos, pp::Vec2d size, 
00038                             const char *binding, 
00039                             listType_t& itemList)
00040  : mp_insensitiveFont(NULL),
00041    m_items(itemList)
00042 {
00043     char *tempbinding;
00044     pp::Vec2d ll;
00045     pp::Vec2d ur;
00046 
00047     m_position = pos;
00048     m_size = size;
00049        
00050     m_arrowWidth = DEFAULT_ARROW_REGION_WIDTH;
00051     m_borderWidth = DEFAULT_BORDER_WIDTH;
00052     m_textPad = LDEFAULT_TEXT_PAD;
00053     m_arrowVertSeparation = DEFAULT_ARROW_VERT_SEPARATION;
00054     m_borderColor = theme.foreground;
00055     m_backgroundColor = theme.background;
00056        
00057        mp_font = pp::Font::get(binding);  
00058        
00059 
00060     /* Create up arrow button */
00061     mp_upButton = new pp::Button( 
00062               pp::Vec2d( 0, 0 ), /* position will be set later */
00063               pp::Vec2d(DEFAULT_ARROW_BUTTON_WIDTH,DEFAULT_ARROW_BUTTON_HEIGHT),
00064               NULL,
00065               NULL );
00066 
00067     tempbinding = "listbox_arrows";
00068 
00069     ll = pp::Vec2d( 2.0/64.0, 17.0/64.0 );
00070     ur = pp::Vec2d( 29.0/64.0, 32.0/64.0 );
00071     mp_upButton->setImage( tempbinding, ll, ur, pp::Color::white );
00072 
00073     ll = pp::Vec2d( 34.0/64.0, 17.0/64.0 );
00074     ur = pp::Vec2d( 61.0/64.0, 32.0/64.0 );
00075     mp_upButton->setDisabledImage( tempbinding, ll, ur, pp::Color::white );
00076 
00077     ll = pp::Vec2d( 34.0/64.0, 49.0/64.0 );
00078     ur = pp::Vec2d( 61.0/64.0, 64.0/64.0 );
00079     mp_upButton->setHilitImage( tempbinding, ll, ur, pp::Color::white );
00080 
00081     ll = pp::Vec2d( 2.0/64.0, 49.0/64.0 );
00082     ur = pp::Vec2d( 29.0/64.0, 64.0/64.0 );
00083     mp_upButton->setClickedImage( tempbinding, ll, ur, pp::Color::white );
00084 
00085        mp_upButton->setActive( true );
00086     mp_upButton->signalClicked.Connect(pp::CreateSlot(this,&Listbox::upButtonClick));
00087 
00088 
00089     /* Create down arrow button */
00090     mp_downButton = new pp::Button( 
00091               pp::Vec2d( 0, 0 ), /* position will be set later */
00092               pp::Vec2d(DEFAULT_ARROW_BUTTON_WIDTH,DEFAULT_ARROW_BUTTON_HEIGHT),
00093               NULL,
00094               NULL );
00095 
00096     tempbinding = "listbox_arrows";
00097 
00098     ll = pp::Vec2d( 2.0/64.0, 1.0/64.0 );
00099     ur = pp::Vec2d( 29.0/64.0, 16.0/64.0 );
00100     mp_downButton->setImage( tempbinding, ll, ur, pp::Color::white );
00101 
00102     ll = pp::Vec2d( 34.0/64.0, 1.0/64.0 );
00103     ur = pp::Vec2d( 61.0/64.0, 16.0/64.0 );
00104     mp_downButton->setDisabledImage( tempbinding, ll, ur, pp::Color::white );
00105 
00106     ll = pp::Vec2d( 34.0/64.0, 33.0/64.0 );
00107     ur = pp::Vec2d( 61.0/64.0, 48.0/64.0 );
00108     mp_downButton->setHilitImage(tempbinding, ll, ur,pp::Color::white );
00109 
00110     ll = pp::Vec2d( 2.0/64.0, 33.0/64.0 );
00111     ur = pp::Vec2d( 29.0/64.0, 48.0/64.0 );
00112     mp_downButton->setClickedImage( tempbinding, ll, ur, pp::Color::white );
00113 
00114        mp_downButton->setActive( true );
00115     mp_downButton->signalClicked.Connect(pp::CreateSlot(this,&Listbox::downButtonClick));
00116 
00117     m_items = itemList;
00118     mi_curItem = m_items.begin();
00119 
00120     m_visible = false;
00121     m_active = false;
00122        m_sensitive = true;
00123 
00124     updateButtonEnabledStates();
00125     updateButtonPositions();
00126 }
00127 
00128 template <class T>
00129 Listbox<T>::~Listbox()
00130 {
00131     setVisible( false );
00132     setActive( false );
00133 
00134     delete mp_upButton;
00135     delete mp_downButton;
00136 }
00137 
00138 template <class T>
00139 void
00140 Listbox<T>::updateButtonEnabledStates()
00141 {
00142     if ( m_items.empty() || !m_sensitive ) {
00143               // disable the buttons because our list
00144               // is empty or insensitive         
00145               mp_upButton->setSensitive( false );
00146               mp_downButton->setSensitive( false );
00147     } else {
00148               if ( mi_curItem == m_items.begin() ) {
00149                      mp_upButton->setSensitive( false );
00150               } else {
00151                      mp_upButton->setSensitive( true );
00152               }
00153 
00154               if ( mi_curItem == --m_items.end() ) {
00155                      mp_downButton->setSensitive( false );
00156               } else {
00157                      mp_downButton->setSensitive( true );
00158               }
00159     }
00160 }
00161 
00162 template <class T>
00163 void
00164 Listbox<T>::updateButtonPositions()
00165 {
00166        mp_upButton->setPosition(pp::Vec2d( 
00167            m_position.x + m_size.x - mp_upButton->getWidth(),
00168            m_position.y + m_size.y / 2.0 + m_arrowVertSeparation / 2.0 ) );
00169 
00170     mp_downButton->setPosition(pp::Vec2d( 
00171            m_position.x + m_size.x - mp_downButton->getWidth(),
00172            m_position.y + m_size.y / 2.0 - 
00173            m_arrowVertSeparation / 2.0 -
00174            mp_upButton->getHeight() ) );
00175 }
00176 
00177 template <class T>
00178 void
00179 Listbox<T>::setPosition(pp::Vec2d pos)
00180 {
00181        Widget::setPosition(pos);
00182        updateButtonPositions();
00183 }
00184 
00185 template <class T>
00186 void
00187 Listbox<T>::setCurrentItem( listIterator_t item )
00188 {
00189     mi_curItem = item;
00190     updateButtonEnabledStates();
00191 }
00192 
00193 template <class T>   
00194 void
00195 Listbox<T>::setItemList( listType_t &itemList )
00196 {
00197     m_items = itemList;
00198     mi_curItem = m_items.begin();
00199     updateButtonEnabledStates();
00200 
00201     UIMgr.setDirty();
00202 }
00203 
00204 template <class T>
00205 void
00206 Listbox<T>::setSensitive(bool sensitive)
00207 {
00208        Widget::setSensitive(sensitive);
00209        updateButtonEnabledStates();
00210 }
00211 
00212 template <class T>
00213 void
00214 Listbox<T>::setInsensitiveFont(const char* binding)
00215 {
00216        mp_insensitiveFont = pp::Font::get(binding);     
00217 }
00218 
00219 template <class T>
00220 bool 
00221 Listbox<T>::gotoNextItem()
00222 {
00223     if ( mi_curItem == --m_items.end() ) {
00224               return false;
00225     }
00226     mp_downButton->simulateMouseClick();
00227     return true;
00228 }
00229 
00230 template <class T>
00231 bool
00232 Listbox<T>::gotoPrevItem()
00233 {
00234     if ( mi_curItem == m_items.begin() ) {
00235               return false;
00236     }
00237     mp_upButton->simulateMouseClick();
00238     return true;
00239 }
00240 
00241 template <class T>
00242 void
00243 Listbox<T>::upButtonClick()
00244 {
00245        if(mi_curItem != m_items.begin()){
00246               mi_curItem--;
00247               signalChange.Emit();
00248        updateButtonEnabledStates();
00249        UIMgr.setDirty();
00250        }
00251 }
00252 
00253 template <class T>
00254 void
00255 Listbox<T>::downButtonClick()
00256 {
00257        if(mi_curItem != --m_items.end()){
00258               mi_curItem++;
00259               signalChange.Emit();
00260        updateButtonEnabledStates();
00261        UIMgr.setDirty();
00262        }      
00263 }
00264 
00265 template <class T>
00266 void
00267 Listbox<T>::draw()
00268 {
00269     glDisable( GL_TEXTURE_2D );
00270 
00271        if(m_sensitive){
00272               if(m_hasFocus){
00273                      glColor4dv( (double*)&theme.focus );
00274               }else{        
00275                      glColor4dv( (double*)&m_borderColor );
00276               }
00277        }else{
00278               glColor4dv( (double*)&theme.insensitive );
00279        }      
00280        
00281     glRectf( m_position.x, 
00282             m_position.y,
00283             m_position.x + m_size.x - m_arrowWidth,
00284             m_position.y + m_size.y );
00285 
00286     glColor4dv( (double*)&m_backgroundColor );
00287 
00288     glRectf( m_position.x + m_borderWidth, 
00289             m_position.y + m_borderWidth,
00290             m_position.x + m_size.x - m_borderWidth - m_arrowWidth,
00291             m_position.y + m_size.y - m_borderWidth );
00292 
00293     glEnable( GL_TEXTURE_2D );
00294 
00295        pp::Font *font = mp_font;
00296        
00297        if(!m_sensitive && mp_insensitiveFont){
00298               font = mp_insensitiveFont;
00299        }
00300        
00301     if (font){
00302               float asc = font->ascender();
00303               float desc = font->descender();
00304                      
00305               font->draw(_((*mi_curItem).name.c_str()),
00306                             m_position.x + m_borderWidth + m_textPad,
00307                             m_position.y + m_size.y/2.0 - asc/2.0 - desc/2);
00308 
00309     }
00310 
00311     mp_upButton->draw();
00312     mp_downButton->draw();
00313 }
00314        
00315 
00316 } //namespace pp