Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

selectionwindow.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003     Copyright (C) 1994-1999  Martin Bickel  and  Marc Schellenberger
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; see the file COPYING. If not, write to the 
00017     Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
00018     Boston, MA  02111-1307  USA
00019 */
00020 
00021 #include "sigc++/retype_return.h"
00022 #include "selectionwindow.h"
00023 #include "../paradialog.h"
00024 
00025 bool SelectionWidget::eventMouseButtonUp (const SDL_MouseButtonEvent *button) 
00026 {
00027    if ( button->type == SDL_MOUSEBUTTONUP && button->button == SDL_BUTTON_LEFT ) {
00028       itemSelected( this );
00029       return true;
00030    }   
00031    return false;
00032 };
00033 
00034 bool SelectionWidget::eventMouseButtonDown (const SDL_MouseButtonEvent *button) 
00035 {
00036    if ( button->type == SDL_MOUSEBUTTONDOWN && button->button == SDL_BUTTON_LEFT ) {
00037       itemMarked( this );
00038       Update();
00039       return true;
00040    }   
00041    return false;
00042 };
00043 
00044 void SelectionWidget::eventBlit ( SDL_Surface * surface, const PG_Rect & src, const PG_Rect & dst )
00045 {
00046    if ( selectionCallBack && selectionCallBack->operator()(this) )
00047       SDL_FillRect( PG_Application::GetScreen(), const_cast<PG_Rect*>(&dst), 0xff888888 );
00048       
00049    display( PG_Application::GetScreen(), src, dst );
00050 };
00051 
00052 
00053 
00054 bool ItemSelectorWidget::moveSelection( int amount ) 
00055 {
00056    WidgetList::iterator i;
00057    if ( !selectedItem ) {
00058       i = widgets.begin();
00059    } else {
00060       i = find( widgets.begin(), widgets.end(), selectedItem );
00061       if ( i != widgets.end() ) {
00062          if ( amount > 0 ) {
00063             if ( widgets.end() - i > amount )
00064                i += amount;
00065             else
00066                i = widgets.end() - 1;
00067          } else
00068          if ( amount < 0 ) {
00069             if ( i - widgets.begin() >= -amount )
00070                i += amount;
00071             else
00072                i = widgets.begin();
00073          }
00074       }
00075    }
00076 
00077    if ( i == widgets.end() )
00078       return false;
00079    
00080    if ( *i != selectedItem ) {
00081       selectedItem = *i;
00082       resetNamesearch();
00083       scrollWidget->ScrollToWidget( *i );
00084       Update();
00085       return true;
00086    } 
00087    return false;
00088 }
00089 
00090 bool ItemSelectorWidget::eventKeyDown(const SDL_KeyboardEvent* key) 
00091 {
00092    if ( key->keysym.sym == SDLK_BACKSPACE ) {
00093       nameSearch->SendBackspace();
00094       /*
00095       ASCString s = nameSearch->GetText();
00096       if ( s.length() > 0 ) {
00097          s.erase( s.length() - 1 );
00098          nameSearch->SetText( s );
00099       }
00100       */
00101       return true;
00102    } 
00103    if ( key->keysym.sym == SDLK_RIGHT )  {
00104       moveSelection(1);
00105       return true;
00106    }
00107    if ( key->keysym.sym == SDLK_LEFT )  {
00108       moveSelection(-1);
00109       return true;
00110    }
00111    if ( key->keysym.sym == SDLK_UP )  {
00112       moveSelection(-columnCount);
00113       return true;
00114    }
00115    if ( key->keysym.sym == SDLK_DOWN )  {
00116       moveSelection(columnCount);
00117       return true;
00118    }
00119    if ( key->keysym.sym == SDLK_HOME )  {
00120       moveSelection(-int(widgets.size()) );
00121       return true;
00122    }
00123    if ( key->keysym.sym == SDLK_END )  {
00124       moveSelection(widgets.size());
00125       return true;
00126    }
00127    if ( key->keysym.sym == SDLK_PAGEUP )  {
00128       moveSelection( -columnCount * visibleRowCount );
00129       return true;
00130    }
00131    if ( key->keysym.sym == SDLK_PAGEDOWN )  {
00132       moveSelection(columnCount * visibleRowCount);
00133       return true;
00134    }
00135 
00136    if ( key->keysym.sym == SDLK_RETURN || key->keysym.sym == SDLK_KP_ENTER) {
00137       if ( namesConstrained ) {
00138          if ( selectedItem && (nameMatch( selectedItem, nameSearch->GetText()) || nameSearch->GetText().length() == 0) ) {
00139             itemSelected( selectedItem, false );
00140             return true;
00141          }   
00142       } else {
00143          if ( nameSearch->GetText().length() ) {
00144             nameEntered( nameSearch->GetText() );
00145             return true;
00146          } else {
00147             if ( selectedItem ) {
00148                itemSelected( selectedItem, false );
00149                return true;
00150             }   
00151          }   
00152       }
00153    } 
00154 
00155       
00156             
00157    if ( key->keysym.unicode <= 255 && key->keysym.unicode >= 0x20 ) {
00158       ASCString newtext = nameSearch->GetText() + char ( key->keysym.unicode );
00159       if ( locateObject( newtext ) || !namesConstrained ) 
00160          nameSearch->SendChar( key->keysym.unicode );
00161       
00162       return true;
00163    }   
00164    
00165    return false;
00166 };
00167 
00168 void ItemSelectorWidget::itemSelected( const SelectionWidget* w, bool mouse )
00169 {
00170    Update();
00171    factory->itemSelected( w, mouse );
00172    sigItemSelected( w );
00173 }
00174 
00175 void ItemSelectorWidget::markItem( const SelectionWidget* w )
00176 {
00177    selectedItem = w;
00178    factory->itemMarked( w );
00179 }
00180 
00181 
00182 bool ItemSelectorWidget::isItemMarked( const SelectionWidget* w )
00183 {
00184    return w == selectedItem;
00185 }
00186       
00187 bool ItemSelectorWidget::locateObject( const ASCString& name ) 
00188 {
00189    for ( WidgetList::iterator i = widgets.begin(); i != widgets.end(); ++i ) {
00190       if ( nameMatch( *i, name )  ) {
00191          markItem( *i );         
00192          scrollWidget->ScrollToWidget( *i );
00193          Update();
00194          return true;
00195       }   
00196    }
00197    return false;
00198 }
00199 
00200 bool ItemSelectorWidget::nameMatch( const SelectionWidget* selection, const ASCString& name )
00201 {
00202    ASCString a = name;
00203    a.toLower();
00204    ASCString b = selection->getName().toLower();
00205    if ( a.length() > 0 && b.length() > 0 )
00206       if ( b.find ( a ) == 0 ) 
00207          return true;
00208    return false;
00209 };   
00210 
00211 
00212 class NonEditableLineEdit : public    PG_LineEdit {
00213    public:
00214       NonEditableLineEdit (PG_Widget *parent, const PG_Rect &r=PG_Rect::null, const std::string &style="LineEdit", int maximumLength=1000000) : PG_LineEdit( parent, r, style, maximumLength)
00215       {
00216          EditBegin();
00217          SetTransparency(255);
00218          SetBorderSize(0);
00219       };
00220       virtual bool   eventKeyDown (const SDL_KeyboardEvent *key) { return false; };
00221       virtual bool   eventFilterKey (const SDL_KeyboardEvent *key) { return true; };
00222       
00223 };
00224 
00225 ItemSelectorWidget::ItemSelectorWidget( PG_Widget *parent, const PG_Rect &r , SelectionItemFactory* itemFactory ) 
00226    : PG_Widget( parent,r ), namesConstrained(true), rowCount(0), scrollWidget( NULL), nameSearch(NULL), selectedItem(NULL), factory( itemFactory ), columnCount(-1), visibleRowCount(-1), selectionCallBack( this, &ItemSelectorWidget::isItemMarked ) {
00227    SetTransparency(255);
00228    reLoad();
00229 
00230    markItem( itemFactory->getDefaultItem() );
00231    int bottom = 0; // itemFactory->getBottomLineHeight();
00232    Emboss* e = new Emboss( this, PG_Rect( 1, Height() - 26 - bottom, Width()-20, 22), true );
00233    nameSearch = new NonEditableLineEdit ( e, PG_Rect( 4,1, e->Width()-4 , e->Height()-2 ));
00234 
00235    // factory->spawnBottonWidgets( this, PG_Rect( 1, Height() - bottom, Width()-20, bottom-1));
00236    // nameSearch = new PG_Label ( this, PG_Rect( 5, Height() - 25, Width() - 10, 20 ));
00237 };
00238 
00239 
00240 void ItemSelectorWidget::constrainNames( bool constrain )
00241 {
00242    namesConstrained = constrain;
00243 }   
00244 
00245 void ItemSelectorWidget::reLoad( bool show ) 
00246 {
00247    int orgx = -1;
00248    int orgy = -1;
00249    if ( scrollWidget ) {
00250       orgx = scrollWidget->GetScrollPosX();
00251       orgy = scrollWidget->GetScrollPosY();
00252    }
00253    delete scrollWidget;
00254    scrollWidget = new PG_ScrollWidget( this , PG_Rect( 0, 0, Width(), Height() - 30 ));
00255    scrollWidget->SetTransparency(255);
00256    widgets.clear();
00257 
00258    int x = 0;
00259    int y = 0;
00260    
00261    factory->restart();
00262    SelectionWidget* w; 
00263    while ( (w = factory->spawnNextItem( scrollWidget, PG_Point(x,y))) ) {
00264    
00265       if ( columnCount < 0 )
00266          columnCount = scrollWidget->Width() / (w->Width() + gapWidth);
00267 
00268       if ( visibleRowCount < 0 )
00269          visibleRowCount = scrollWidget->Height() / (w->Height() + gapWidth);
00270 
00271       w->itemSelected.connect( SigC::bind( SigC::slot( *this, &ItemSelectorWidget::itemSelected ), true ));
00272       w->itemMarked.connect( SigC::slot( *this, &ItemSelectorWidget::markItem ));
00273       w->setSelectionCallback( &selectionCallBack );
00274       widgets.push_back ( w );
00275       
00276       x += w->Width() + gapWidth;
00277       if ( x + w->Width() + gapWidth >= scrollWidget->Width() ) {
00278          x = 0; 
00279          y += w->Height() + gapWidth;
00280       }
00281    }
00282 
00283    if ( orgx >= 0 && orgy >= 0 )
00284       scrollWidget->ScrollTo ( orgx, orgy );
00285    
00286    if ( show ) 
00287       // scrollWidget->Update();
00288       scrollWidget->Show();
00289 }
00290 
00291 
00292 void ItemSelectorWidget::resetNamesearch()
00293 {
00294    nameSearch->SetText( "" );
00295 }
00296 
00297 ItemSelectorWidget::~ItemSelectorWidget()
00298 {
00299    delete factory;
00300 }
00301 
00302 
00303 
00304 ItemSelectorWindow::ItemSelectorWindow( PG_Widget *parent, const PG_Rect &r , const ASCString& title, SelectionItemFactory* itemFactory )
00305    : ASC_PG_Dialog( parent,r, title)
00306 {
00307    SetTransparency( 0 );
00308    
00309    itemSelector = new ItemSelectorWidget( this, PG_Rect( 5, GetTitlebarHeight () + 2, Width()-5, Height()- GetTitlebarHeight ()- 5 ), itemFactory );
00310    
00311    itemSelector->sigItemSelected.connect(  SigC::slot( *this, &ItemSelectorWindow::itemSelected ));
00312    itemSelector->sigQuitModal.connect( SigC::slot( *this, &ItemSelectorWindow::QuitModal));
00313 };
00314 
00315 void ItemSelectorWindow::itemSelected( const SelectionWidget* )
00316 {
00317    Hide();
00318    QuitModal();
00319 }
00320 
00321 bool ItemSelectorWindow::eventKeyDown(const SDL_KeyboardEvent* key)
00322 {
00323    if ( key->keysym.sym == SDLK_ESCAPE )  {
00324       QuitModal();
00325       return true;
00326    }
00327    return false;
00328 }
00329 
00330 int ItemSelectorWindow::RunModal()
00331 {
00332    itemSelector ->resetNamesearch();
00333    return PG_Window::RunModal();
00334 }
00335 
00336 void ItemSelectorWindow::reLoad()
00337 {
00338    itemSelector->reLoad();
00339 }

Generated on Tue Jun 24 01:27:51 2008 for Advanced Strategic Command by  doxygen 1.4.2