00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
00096
00097
00098
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;
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
00236
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
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 }