src/ui/uMenu.h

Go to the documentation of this file.
00001 /*
00002 
00003 *************************************************************************
00004 
00005 ArmageTron -- Just another Tron Lightcycle Game in 3D.
00006 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
00007 Copyright (C) 2004  Armagetron Advanced Team (http://sourceforge.net/projects/armagetronad/) 
00008 
00009 **************************************************************************
00010 
00011 This program is free software; you can redistribute it and/or
00012 modify it under the terms of the GNU General Public License
00013 as published by the Free Software Foundation; either version 2
00014 of the License, or (at your option) any later version.
00015 
00016 This program is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 GNU General Public License for more details.
00020 
00021 You should have received a copy of the GNU General Public License
00022 along with this program; if not, write to the Free Software
00023 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00024   
00025 ***************************************************************************
00026 
00027 */
00028 
00029 #ifndef ArmageTron_MENU_H
00030 #define ArmageTron_MENU_H
00031 
00032 #include "rFont.h"
00033 #include "tList.h"
00034 #include "tString.h"
00035 #include "tCallback.h"
00036 #include "tLocale.h"
00037 
00038 #include "rSDL.h"
00039 #ifndef DEDICATED
00040 #include <SDL_events.h>
00041 #endif
00042 
00043 #include <deque>
00044 
00045 #include "defs.h"
00046 
00047 class uMenuItem;
00048 
00049 class uMenu{
00050     friend class uMenuItem;
00051 
00052 protected:
00053     tList<uMenuItem>      items;
00054     static FUNCPTR       idle;
00055 
00056     REAL menuTop;
00057     REAL menuBot;
00058     REAL yOffset;
00059 
00060     bool                 exitFlag;
00061 
00062     REAL                 spaceBelow;
00063     REAL                 center;
00064 
00065     int                  selected;
00066 
00067     REAL YPos(int num);
00068 public:
00069     static bool          wrap;
00070     static bool          quickexit;
00071     static bool          exitToMain;
00072 
00073     tOutput              title;
00074 
00075     FUNCPTR IdleFunc(){return idle;}
00076     static void SetIdle(FUNCPTR idle_func) {idle=idle_func;}
00077 
00078     // poll input, return true if ESC was pressed
00079     static bool IdleInput();
00080 
00081     void SetCenter(REAL c) {center=c;}
00082     void SetTop(REAL t) {menuTop=t;}
00083     void SetBot(REAL b) {menuBot=b;spaceBelow=1+menuBot;}
00084     void SetSelected(int s) {selected = s;}
00085     int  NumItems()         {return items.Len();}
00086     uMenuItem* Item(int i)  { return items[i]; }
00087     void AddItem(uMenuItem* item);
00088     void RemoveItem(uMenuItem* item);
00089 
00090 #ifdef SLOPPYLOCALE
00091     uMenu(const char *t,bool exit_item=true);
00092 #endif
00093     uMenu(const tOutput &t,bool exit_item=true);
00094     virtual ~uMenu();
00095 
00097     inline void Enter(){OnEnter();}
00098 
00099     void ReverseItems();
00100 
00101     // paints a nice background
00102     static void GenericBackground();
00103 
00104     // marks the menu for exit
00105     inline void Exit(){OnExit();}
00106 
00107     void RequestSpaceBelow(REAL x){
00108         if (spaceBelow<x)
00109             spaceBelow=x;
00110     }
00111 
00112     // print a big message and a small interpretation
00113     static bool Message(const tOutput& message, const tOutput& interpretation, REAL timeout = -1);
00114 
00116     static bool MenuActive();
00117 protected:
00119     virtual void HandleEvent( SDL_Event event );
00120 
00122     virtual void OnEnter();
00123 
00125     virtual void OnExit();
00126 
00127     int GetNextSelectable(int start);
00128     int GetPrevSelectable(int start);
00129 
00131     virtual void OnRender();
00132 };
00133 
00134 
00135 // *****************************************************
00136 
00137 class uMenuItem{
00138     friend class uMenu;
00139 
00140     int idnum;
00141     uMenuItem(){};
00142 protected:
00143     uMenu  *menu;
00144     tOutput helpText;
00145 
00146     void DisplayText(REAL x,REAL y,const char *text,bool selected,
00147                      REAL alpha=1,int center=0,int cursor=0,int cursorPos=0, rTextField::ColorMode colorMode = rTextField::COLOR_USE, float maxWidth=2. );
00148     void DisplayTextSpecial(REAL x,REAL y,const char *text,bool selected,
00149                             REAL alpha=1,int center=0);
00150 public:
00151     uMenuItem(uMenu *M,const tOutput &help)
00152             :idnum(-1),menu(M),helpText(help){
00153         menu->items.Add(this,idnum);
00154     }
00155 
00156 #ifdef SLOPPYLOCALE
00157     uMenuItem(uMenu *M,const char *help)
00158             :idnum(-1),menu(M),helpText(help){
00159         menu->items.Add(this,idnum);
00160     }
00161 #endif
00162 
00163     virtual ~uMenuItem()
00164     {
00165         if (menu && idnum >= 0)
00166             menu->items.Remove(this,idnum);
00167     }
00168 
00169 virtual tString Help(){return tString(helpText);}
00170     // displays the menuitem at position x,y. set selected to true
00171     // if the item is currently under the cursor
00172     virtual void Render(REAL ,REAL ,REAL =1,bool =0){};
00173 
00174     virtual void RenderBackground(){
00175         menu->GenericBackground();
00176     };
00177 
00178     // if the user presses left/right on menuitem
00179     virtual void LeftRight(int ){}; //lr=-1:left lr=+1: right
00180     virtual void LeftRightRelease(){};
00181 
00182     virtual void Enter(){}; // if the user presses enter/space on menu
00183 
00184     virtual bool Event(SDL_Event &){return false;} // if the key c is
00185     // pressed,mouse moved ...
00186     // while menuitem is active; return value: key was used
00187 
00188     virtual REAL SpaceRight(){return 0;}
00189 
00190     int GetID(){return idnum;}
00191 
00192     virtual bool IsSelectable(){return true;};
00193 
00194 protected:
00195     void SetColor( bool selected, REAL alpha );            
00196 };
00197 
00198 
00199 // *****************************************************
00200 // Menu Exit
00201 // *****************************************************
00202 
00203 class uMenuItemExit:public uMenuItem{
00204     tOutput t;
00205 
00206     static const tOutput& ExitText();
00207     static const tOutput& ExitHelp();
00208 
00209 public:
00210     uMenuItemExit(uMenu *M,
00211                   const tOutput &text = ExitText(),
00212                   const tOutput &help = ExitHelp())
00213             :uMenuItem(M,help)
00214     ,t(text){}
00215 
00216     // displays the menuitem at position x,y. set selected to true
00217     // if the item is currently under the cursor
00218     virtual void Render(REAL x,REAL y,REAL alpha=1,bool selected=0){
00219         DisplayTextSpecial(x,y,tString(t),selected,alpha);
00220     };
00221 
00222     virtual void Enter(){menu->Exit();}
00223     // if the user presses enter/space on menu
00224 };
00225 
00226 // *****************************************************
00227 // Selection
00228 // *****************************************************
00229 
00230 template<class T> class uSelectItem{
00231 public:
00232     int idnum;
00233 
00234     tOutput description;
00235     tOutput helpText;
00236     T value;
00237 
00238     uSelectItem(const tOutput& desc,const tOutput& help,T val)
00239             :idnum(-1),description(desc),helpText(help),value(val){}
00240 };
00241 
00242 template<class T> class uMenuItemSelection:public uMenuItem{
00243 protected:
00244     tList<uSelectItem<T> >      choices;
00245     tOutput                     title;
00246     int                         select;
00247     T *                         target;
00248 public:
00249 #ifdef SLOPPYLOCALE
00250     uMenuItemSelection(uMenu *m,
00251                        const char* tit,const char *help,
00252                        T &targ)
00253             :uMenuItem(m,help),title(tit),select(0),target(&targ){}
00254 #endif
00255 
00256     uMenuItemSelection(uMenu *m,
00257                        const tOutput &tit,const tOutput &help,
00258                        T &targ)
00259             :uMenuItem(m,help),title(tit),select(0),target(&targ){}
00260 
00261     ~uMenuItemSelection(){
00262         Clear();
00263     }
00264 
00265     void Clear(){
00266         for(int i=choices.Len()-1;i>=0;i--){
00267             uSelectItem<T> *x=choices(i);
00268             choices.Remove(x,x->idnum);
00269             delete x;
00270         }
00271         select=0;
00272     }
00273 
00274     void NewChoice(uSelectItem<T> *c){
00275         choices.Add(c,c->idnum);
00276     }
00277 
00278     void NewChoice(const tOutput& desc,const tOutput& help,T val){
00279         uSelectItem<T> *x=new uSelectItem<T>(desc,help,val);
00280         NewChoice(x);
00281     }
00282 
00283     virtual void LeftRight(int lr){
00284         select+=lr;
00285         if(select>=choices.Len())
00286             select=choices.Len()-1;
00287         if(select<0)
00288             select=0;
00289         if (choices.Len())
00290             *target=choices(select)->value;
00291     }
00292 
00293     virtual void Render(REAL x,REAL y,REAL alpha=1,bool selected=0){
00294         for(int i=choices.Len()-1;i>=0;i--)
00295             if (choices(i)->value==*target)
00296                 select=i;
00297 
00298         DisplayText(REAL(x-.02),y,title,selected,alpha,1);
00299         if (choices.Len()>0)
00300             DisplayText(REAL(x+.02),y,choices(select)->description,selected,alpha,-1);
00301     }
00302 
00303     virtual tString Help(){
00304         tString ret;
00305         ret << helpText;
00306         ret << "\n";
00307         ret << choices(select)->helpText;
00308         return ret;
00309     }
00310 
00311 };
00312 
00313 template<class T> class uSelectEntry{
00314 public:
00315     uSelectEntry(uMenuItemSelection<T> &sel,
00316                  const char *desc,
00317                  const char *help,T val){
00318         sel.NewChoice(desc,help,val);
00319     }
00320 };
00321 
00322 // *****************************************
00323 //               Toggle
00324 // *****************************************
00325 
00326 class uMenuItemToggle: public uMenuItemSelection<bool>{
00327     void NewChoice(uSelectItem<bool> *c);
00328     void NewChoice(const char *desc,bool val);
00329 public:
00330 #ifdef SLOPPYLOCALE
00331     uMenuItemToggle(uMenu *m,const char *tit,
00332                     const char *help,bool &targ);
00333 #endif
00334     uMenuItemToggle(uMenu *m,const tOutput& title,
00335                     const tOutput& help,bool &targ);
00336     ~uMenuItemToggle();
00337 
00338     virtual void LeftRight(int);
00339     virtual void Enter();
00340 };
00341 
00342 
00343 // *****************************************
00344 //               Integer Choose
00345 // *****************************************
00346 
00347 class uMenuItemInt:public uMenuItem{
00348 protected:
00349     tOutput title;
00350     int &target;
00351     int Min,Max;
00352     int Step;
00353 public:
00354     /*
00355       uMenuItemInt(uMenu *m,const char *tit,
00356       const char *help,int &targ,
00357       int mi,int ma,int step=1);
00358     */
00359     uMenuItemInt(uMenu *m,const tOutput &title,
00360                  const tOutput &help,int &targ,
00361                  int mi,int ma,int step=1);
00362 
00363     ~uMenuItemInt(){};
00364 
00365     virtual void LeftRight(int);
00366 
00367     virtual void Render(REAL x,REAL y,REAL alpha=1,bool selected=0);
00368 };
00369 
00370 
00371 
00372 
00373 // *****************************************************
00374 //  String query
00375 // *****************************************************
00376 
00377 
00378 class uMenuItemString: public uMenuItem{
00379 protected:
00380     tOutput  description;
00381     tString *content;
00382     int      cursorPos;
00383     int         maxLength_;
00384 
00385     // color mode used for rendering
00386     rTextField::ColorMode colorMode_;
00387 public:
00388     uMenuItemString(uMenu *M,const tOutput& desc,
00389                     const tOutput& help,tString &c, int maxLength = 1024 );
00390     virtual ~uMenuItemString(){}
00391 
00392     virtual void Render(REAL x,REAL y,REAL alpha=1,bool selected=0);
00393 
00394     virtual bool Event(SDL_Event &e);
00395 
00396     uMenu *MyMenu(){return menu;}
00397 
00398     void SetColorMode( rTextField::ColorMode colorMode )
00399     {
00400         colorMode_ = colorMode;
00401     }
00402 
00403     rTextField::ColorMode GetColorMode() const
00404     {
00405         return colorMode_;
00406     }
00407 };
00408 
00412 class uAutoCompleter {
00413 protected:
00414     std::deque<tString> &m_PossibleWords; 
00415     int m_LastCompletion;
00416     bool m_ignorecase;
00417 
00418     virtual int FindLengthOfLastWord(tString &string, unsigned pos); 
00419     virtual void FindPossibleWords(tString word, std::deque<tString> &results); 
00420     virtual tString FindClosestMatch(tString &word, std::deque<tString> &results); 
00421     virtual void ShowPossibilities(std::deque<tString> &results, tString &word); 
00422     virtual int DoCompletion(tString &string, int pos, int len, tString &match); 
00423     virtual int DoFullCompletion(tString &string, int pos, int len, tString &match); 
00424     virtual int TryCompletion(tString &string, unsigned pos, unsigned len); 
00425 
00426     virtual tString Simplify(tString const &str); 
00427 public:
00428     uAutoCompleter(std::deque<tString> &words); 
00429     virtual int Complete(tString &string, unsigned pos); 
00430 
00431     virtual ~uAutoCompleter(){}
00432     void SetIgnorecase(bool ignorecase); 
00433 };
00434 
00436 class uMenuItemStringWithHistory : protected uMenuItemString {
00437 public:
00439 class history_t : public std::deque<tString> {
00440         char const *m_filename;
00441     public:
00442         history_t(char const *filename); 
00443         ~history_t(); 
00444     };
00445 protected:
00446     history_t &m_History; 
00447     unsigned int m_HistoryPos; 
00448     unsigned int m_HistoryLimit; 
00449     uAutoCompleter *m_Completer; 
00450     bool m_Searchmode; 
00451     bool m_SearchFailing; 
00452 public:
00453     uMenuItemStringWithHistory(uMenu *M,const tOutput& desc, const tOutput& help,tString &c, int maxLength, history_t &history, int limit, uAutoCompleter *completer = 0); 
00454 
00455     ~uMenuItemStringWithHistory(); 
00456 
00457     virtual bool Event(SDL_Event &e); 
00458     virtual void Render(REAL x,REAL y,REAL alpha=1,bool selected=0); 
00459 };
00460 
00461 // *****************************************************
00462 //  Submenu
00463 // *****************************************************
00464 
00465 
00466 class uMenuItemSubmenu: public uMenuItem{
00467     uMenu *submenu;
00468 public:
00469     uMenuItemSubmenu(uMenu *M,uMenu *s,
00470                      const tOutput& help);
00471     virtual ~uMenuItemSubmenu(){}
00472 
00473     virtual void Render(REAL x,REAL y,REAL alpha=1,bool selected=0);
00474 
00475     virtual void Enter();
00476 };
00477 
00478 
00479 // *****************************************************
00480 //  generic action
00481 // *****************************************************
00482 
00483 class uMenuItemAction: public uMenuItem{
00484 public:
00485     uMenuItemAction(uMenu *M,const tOutput& name,
00486                     const tOutput& help );
00487 
00488     virtual ~uMenuItemAction(){}
00489 
00490     virtual void Render(REAL x,REAL y,REAL alpha=1,bool selected=0);
00491 
00492     virtual void Enter() = 0;
00493 protected:
00494     tOutput  name_;
00495 };
00496 
00497 // *****************************************************
00498 //  Execute function
00499 // *****************************************************
00500 
00501 
00502 class uMenuItemFunction: public uMenuItemAction{
00503     FUNCPTR  func;
00504 public:
00505     uMenuItemFunction(uMenu *M,const tOutput& name,
00506                       const tOutput& help,FUNCPTR f);
00507 
00508     virtual ~uMenuItemFunction(){}
00509 
00510     virtual void Enter();
00511 };
00512 
00513 
00514 class uMenuItemFunctionInt: public uMenuItemAction{
00515     INTFUNCPTR  func;
00516     int         arg;
00517 public:
00518     uMenuItemFunctionInt(uMenu *M,const tOutput& name,
00519                          const tOutput& help,INTFUNCPTR f,int arg);
00520 
00521     virtual ~uMenuItemFunctionInt(){}
00522 
00523     virtual void Enter();
00524 };
00525 
00526 // *****************************************************
00527 //  File Selection (added by k)
00528 // *****************************************************
00529 
00530 class uMenuItemFileSelection: public uMenuItemSelection<tString>
00531 {
00532     void NewChoice( uSelectItem<bool> * );
00533     void NewChoice( char *, bool );
00534 protected:
00535     tString dir_;
00536     tString fileSpec_;
00537     int     getFilesFlag_;
00538     bool    formatName_;
00539     tString defaultFileName_;
00540     tString defaultFilePath_;
00541 public:
00542     uMenuItemFileSelection( uMenu *m, char *tit, const char *help, tString& targ,
00543                             const char *dir, const char *fileSpec, int getFilesFlag = 0, bool formatName = true )
00544             :uMenuItemSelection<tString>( m, tit, help, targ )
00545     {
00546         SetParams( dir, fileSpec, getFilesFlag, formatName, "", "" );
00547         Reload();
00548     }
00549 
00550     uMenuItemFileSelection( uMenu *m, char *tit, const char *help, tString& targ,
00551                             const char *dir, const char *fileSpec,
00552                             const char *defaultFileName, const char *defaultFilePath,
00553                             int getFilesFlag = 0, bool formatName = true )
00554             :uMenuItemSelection<tString>( m, tit, help, targ )
00555     {
00556         SetParams( dir, fileSpec, getFilesFlag, formatName, defaultFileName, defaultFilePath );
00557         Reload();
00558     }
00559 
00560     virtual ~uMenuItemFileSelection() {};
00561 
00562     void SetDir( const char *dir ) { dir_ = dir; }; const
00563     void SetFileSpec( const char *fileSpec ) { fileSpec_ = fileSpec; }; const
00564     void SetFormatName( bool formatName ) { formatName_ = formatName; }; const
00565     void SetGetFilesFlag( int getFilesFlag ) { getFilesFlag_ = getFilesFlag; } const
00566     void SetDefaultFileName( const char *defaultFileName ) { defaultFileName_ = defaultFileName; }; const
00567     void SetDefaultFilePath( const char *defaultFilePath ) { defaultFilePath_ = defaultFilePath; }; const
00568 
00569     void SetParams( const char *dir, const char *fileSpec, int getFilesFlag,
00570                     bool formatName, const char *defaultFileName, const char *defaultFilePath )
00571     {
00572         SetDir( dir );
00573         SetFileSpec( fileSpec );
00574         SetGetFilesFlag( getFilesFlag );
00575         SetFormatName( formatName );
00576         SetDefaultFileName( defaultFileName );
00577         SetDefaultFilePath( defaultFilePath );
00578     }
00579 
00580     void Reload();
00581 
00582     void LoadDirectory( const char *dir, const char *fileSpec, bool formatName = true );
00583 
00584     void AddFile( const char *fileName, const char *filePath, bool formatName = true );
00585 };
00586 
00587 // *****************************************************
00588 // Menu Enter/Leave-Callback
00589 // *****************************************************
00590 
00591 class uCallbackMenuEnter: public tCallback{
00592 public:
00593     uCallbackMenuEnter(AA_VOIDFUNC *f);
00594     static void MenuEnter();
00595 };
00596 
00597 class uCallbackMenuLeave: public tCallback{
00598 public:
00599     uCallbackMenuLeave(AA_VOIDFUNC *f);
00600     static void MenuLeave();
00601 };
00602 
00603 class uCallbackMenuBackground: public tCallback{
00604 public:
00605     uCallbackMenuBackground(AA_VOIDFUNC *f);
00606     static void MenuBackground();
00607 };
00608 
00609 
00610 inline void uMenu::AddItem(uMenuItem* item)     { items.Add(item, item->idnum); }
00611 inline void uMenu::RemoveItem(uMenuItem* item)  { items.Remove(item, item->idnum); }
00612 
00613 #endif
00614 

Generated on Sat Mar 15 22:56:14 2008 for Armagetron Advanced by  doxygen 1.5.4