Hosting courtesy of Sourceforge

SourceForge Logo
Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members  

MenuManager.cpp

Go to the documentation of this file.
00001 //
00002 //                                 MenuManager.cpp
00003 //                             -------------------
00004 //    begin                : Tue May 14 2002
00005 //    copyright           : (C) 2002 by Rob Renaud
00006 //    email                : rrenaud@eden.rutgers.edu
00007 //
00008 //   This program is free software; you can redistribute it and/or modify
00009 //   it under the terms of the GNU General Public License as published by
00010 //   the Free Software Foundation; either version 2 of the License, or
00011 //   (at your option) any later version.
00012 //
00013 
00014 #include "MenuManager.h"
00015 
00016 #include <cctype>
00017 #include "../Game/PlayerController.h"
00018 #include "../Util/GeneralException.h"
00019 #include "../Util/StringUtil.h"
00020 #include "../Util/STL_Helper.h"
00021 
00022 using namespace Menu;
00023 
00024 bool KeyMapContainer::initialized=false;
00025 KeyToStringMap_t KeyMapContainer::keyStringMap;
00026 StringToKeyMap_t KeyMapContainer::stringKeyMap;
00027 
00028 #ifdef HAVE_SDL_TTF
00029 
00030 MenuManager::MenuManager(const std::string& t, const SDL_Color& titleColor, const SDL_Color& bg ) :
00031 title(t),
00032 fontSize(DEFAULT_FONT_SIZE),
00033 titleCol(titleColor),
00034 bgCol(bg)
00035 {
00036         font = TTF_OpenFont(DEFAULT_FONT, DEFAULT_FONT_SIZE);
00037         if (font==NULL) throw Util::GeneralException(std::string("font ") + DEFAULT_FONT + " could not be opened",
00038                 __FILE__, __LINE__);
00039         
00040         currentSelection=0;
00041 }
00042 
00043 bool MenuManager::run(SDL_Surface* screen) {
00044         itemVec[currentSelection]->select();
00045         SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, bgCol.r, bgCol.g, bgCol.b));
00046         while (1) {
00047                 SDL_Event event;
00048                 bool somethingHappened=false;
00049                 while (SDL_PollEvent(&event)) {
00050                         somethingHappened=true;
00051                         MenuHandleResult result = itemVec[currentSelection]->handleEvent(&event);
00052                         if (MENU_QUIT == result) return true;
00053                         if (EVENT_HANDLED == result) {
00054                                 SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, bgCol.r, bgCol.g, bgCol.b));
00055                                 continue;
00056                         }
00057 
00058                         switch (event.type) {
00059                                 case SDL_KEYDOWN:
00060                                         switch (event.key.keysym.sym) {
00061                                                 case SDLK_ESCAPE:       return true; break;
00062                                                 case SDLK_DOWN: {
00063                                                         itemVec[currentSelection]->deselect();
00064                                                         currentSelection = (currentSelection + 1) % itemVec.size();
00065                                                         itemVec[currentSelection]->select();
00066                                                 }
00067                                                 break;
00068                                                 case SDLK_UP: {
00069                                                         itemVec[currentSelection]->deselect();
00070                                                         currentSelection = (currentSelection == 0) ? itemVec.size() - 1 : currentSelection -1;
00071                                                         itemVec[currentSelection]->select();
00072                                                 }
00073                                                 break;                                          
00074                                         }  // switch (event.key.keysym.sym)
00075                                 break;
00076                         }   // switch (event.type)
00077                 }  // while (SDL_PollEvent())
00078         
00079                 if (somethingHappened) {  // something happened, re-render the menus
00080                         SDL_Surface* titleText = TTF_RenderText_Solid(font, title.c_str(), titleCol);
00081                         if (titleText == NULL) throw Util::GeneralException("Menu could not render text title", __FILE__, __LINE__);
00082                         SDL_Rect rect;
00083                 
00084                         rect.x = TEXT_CENTER_X - titleText->w/2;
00085                         rect.y = TITLE_OFFSET_FROM_TOP;                 
00086 
00087                         SDL_BlitSurface(titleText, NULL, screen, &rect);
00088                         SDL_FreeSurface(titleText);
00089 
00090                         rect.x = TEXT_CENTER_X;
00091                         rect.y += VERTICAL_SPACING + DEFAULT_FONT_SIZE;
00092                         for (std::vector<MenuItem*>::iterator i = itemVec.begin(); i != itemVec.end(); i++) {
00093                                 rect.y += VERTICAL_SPACING + DEFAULT_FONT_SIZE;
00094                                 (*i)->draw(screen, font, rect.x, rect.y);
00095                         }
00096 
00097                         SDL_Flip(screen);
00098                 }
00099         }                                               
00100 }
00101 
00102 void MenuManager::addMenuItem(MenuItem* item) {
00103         itemVec.push_back(item);
00104 }
00105 
00106 MenuManager::~MenuManager() {
00107         Util::freeDynamicContainer(itemVec);
00108         TTF_CloseFont(font);
00109 }
00110 
00111 DefaultMenuItem::DefaultMenuItem(const std::string& n, const SDL_Color& selected, const SDL_Color& deselected) :
00112 name(n),
00113 selectedColor(selected),
00114 deselectedColor(deselected),
00115 isSelected(false)
00116 {
00117 }
00118 
00119 void DefaultMenuItem::select() {
00120         isSelected=true;
00121 }
00122 
00123 void DefaultMenuItem::deselect() {
00124         isSelected=false;
00125 }
00126 
00127 void DefaultMenuItem::draw(SDL_Surface* surf, TTF_Font* font, int centerX, int centerY) {
00128         SDL_Surface* text = NULL;
00129         SDL_Rect r;
00130 
00131         text = TTF_RenderText_Solid(font, name.c_str(), getCurrentColor());
00132         
00133         r.x = centerX - text->w / 2;
00134         r.y = centerY - text->h / 2;
00135 
00136         SDL_BlitSurface(text, NULL, surf, &r);
00137         SDL_FreeSurface(text);
00138 }       
00139 
00140 const SDL_Color& DefaultMenuItem::getCurrentColor() {
00141         if (isSelected) return selectedColor;
00142         return deselectedColor;
00143 }
00144 
00145 BooleanItem::BooleanItem(const std::string& name, bool& b,  const SDL_Color& s, const SDL_Color& u) :
00146 DefaultMenuItem(name, s, u),
00147 optionEnabled(b)
00148 { }
00149 
00150 MenuHandleResult BooleanItem::handleEvent(SDL_Event* e) {
00151         if (e->type == SDL_KEYDOWN && e->key.keysym.sym == SDLK_RETURN) {
00152                 optionEnabled = !optionEnabled;
00153                 return EVENT_HANDLED;
00154         }
00155         return EVENT_PASSED;
00156 }
00157 
00158 void BooleanItem::draw(SDL_Surface* surf, TTF_Font* font, int centerX, int centerY) {
00159         DefaultMenuItem::draw(surf, font, centerX, centerY);
00160         SDL_Surface* optionText = NULL;
00161         SDL_Rect r;     
00162 
00163         if (optionEnabled)  optionText = TTF_RenderText_Solid(font, "enabled", getCurrentColor());
00164         else                            optionText = TTF_RenderText_Solid(font, "disabled", getCurrentColor());
00165 
00166         r.x = centerX + INPUT_HORIZ_SPACE;
00167         r.y = centerY - optionText->h/2;
00168         r.w = optionText->w;
00169         r.h = optionText->h;
00170 
00171         SDL_BlitSurface(optionText, NULL, surf, &r);
00172         SDL_FreeSurface(optionText);
00173 }
00174 
00175 GotoSubMenu::GotoSubMenu(const std::string& title, MenuManager& m, SDL_Surface* surf,
00176                                                                 const SDL_Color& s, const SDL_Color& u) :
00177 DefaultMenuItem(title, s, u),
00178 menu(m),
00179 screen(surf)
00180 { }
00181 
00182 MenuHandleResult GotoSubMenu::handleEvent(SDL_Event* e) {
00183         if (e->type == SDL_KEYDOWN && e->key.keysym.sym == SDLK_RETURN) {
00184                 //SDL_FillRect(screen, NULL, 0); // black out screen
00185                 menu.run(screen);
00186                 return EVENT_HANDLED;
00187         }
00188         return EVENT_PASSED;
00189 }
00190 
00191 InputGetter::InputGetter(const std::string& n, const SDL_Color& s, const SDL_Color& u, const SDL_Color& a) :
00192 DefaultMenuItem(n, s, u),
00193 activeCol(a),
00194 active(false)
00195 { }
00196 
00197 MenuHandleResult InputGetter::handleEvent(SDL_Event* e) {
00198         if (e->type != SDL_KEYDOWN) return EVENT_PASSED;
00199         SDLKey newKey = e->key.keysym.sym;
00200 
00201         // not changing, hit enter to start messing with it     
00202         if (!active) {
00203                 if (newKey != SDLK_RETURN)      return EVENT_PASSED;
00204                 else { // enter (return) was pressed, become active
00205                         active = true;
00206                         return EVENT_HANDLED;
00207                 }
00208         }               
00209         
00210         if (newKey == SDLK_ESCAPE) {    // key was active and escape was pressed, become inactive
00211                 active = false;
00212                 return EVENT_HANDLED;
00213         }
00214         return EVENT_PASSED;
00215 }
00216 
00217 const SDL_Color& InputGetter::getCurrentColor() {
00218         if (active) return activeCol;
00219         return DefaultMenuItem::getCurrentColor();
00220 }
00221 
00222 KeyInputter::KeyInputter(const std::string& title, SDLKey& k,
00223                                                          const SDL_Color & sel, const SDL_Color& unsel, const SDL_Color& act) :
00224 InputGetter(title, sel, unsel, act),
00225 key(k)
00226 { }
00227 
00228 void KeyInputter::draw(SDL_Surface* surf, TTF_Font* font, int centerX, int centerY) {
00229         InputGetter::draw(surf, font, centerX, centerY);
00230 
00231         SDL_Surface* keyText=NULL;
00232         std::string keyName;
00233         SDL_Rect r;
00234 
00235         const KeyToStringMap_t& keyMap = KeyMapContainer::getKeyToStringMap();
00236         if (keyMap.find(key) != keyMap.end())   keyName = keyMap.find(key)->second;
00237         else                                                                    keyName = "No Key";
00238 
00239         keyText = TTF_RenderText_Solid(font, keyName.c_str(), getCurrentColor());
00240 
00241         r.x = centerX + INPUT_HORIZ_SPACE;
00242         r.y = centerY - keyText->h /2;
00243         r.w = keyText->w;
00244         r.h = keyText->h;
00245 
00246         SDL_BlitSurface(keyText, NULL, surf, &r);
00247         SDL_FreeSurface(keyText);       
00248 }
00249 
00250 MenuHandleResult KeyInputter::handleEvent(SDL_Event* e) {
00251         MenuHandleResult r = InputGetter::handleEvent(e);
00252         if (EVENT_HANDLED == r) return EVENT_HANDLED;
00253 
00254         if (isActive()) {
00255                 SDLKey newKey = e->key.keysym.sym;      
00256                 
00257         const KeyToStringMap_t& keyMap = KeyMapContainer::getKeyToStringMap();
00258 
00259                 if (keyMap.find(newKey) != keyMap.end()) {
00260                         key = newKey;
00261                         return EVENT_HANDLED;
00262                 }
00263         }
00264         
00265         return EVENT_PASSED;
00266 }
00267 
00268 IntInputter::IntInputter(const std::string& name, int& i, int min_, int max_,
00269         const SDL_Color& s, const SDL_Color& u, const SDL_Color& a) :
00270 InputGetter(name, s, u, a),
00271 storageInt(i),
00272 min(min_),
00273 max(max_)
00274 { }
00275 
00276 #include <iostream>
00277 
00278 MenuHandleResult IntInputter::handleEvent(SDL_Event* e) {
00279         MenuHandleResult r = InputGetter::handleEvent(e);
00280         if (EVENT_HANDLED == r) return EVENT_HANDLED;
00281 
00282         if (isActive()) {
00283                 if (e->type != SDL_KEYDOWN) return EVENT_PASSED;
00284 
00285                 SDLKey newKey = e->key.keysym.sym;
00286 
00287                 if (newKey == SDLK_UP) {
00288                         storageInt++;
00289                         if (storageInt > max) storageInt = max;
00290                         return EVENT_HANDLED;
00291                 }
00292 
00293                 if (newKey == SDLK_DOWN) {
00294                         storageInt--;
00295                         if (storageInt < min) storageInt = min;
00296                         return EVENT_HANDLED;
00297                 }
00298 
00299                 std::string keyName;
00300         const KeyToStringMap_t& keyMap = KeyMapContainer::getKeyToStringMap();
00301                 if (keyMap.find(newKey) != keyMap.end()) keyName = keyMap.find(newKey)->second;
00302 
00303                 int pressedInt=-1;
00304                 for (size_t i = 0; i < keyName.length(); i++) {
00305                         if (isdigit(keyName[i])) pressedInt = keyName[i] - '0';
00306                 }
00307         
00308                 if (pressedInt >= min && pressedInt <= max) {
00309                         storageInt = pressedInt;
00310                         return EVENT_HANDLED;
00311                 }
00312     }
00313         return EVENT_PASSED;
00314 }
00315 
00316 void IntInputter::draw(SDL_Surface* surf, TTF_Font* font, int centerX, int centerY) {
00317         InputGetter::draw(surf, font, centerX, centerY);
00318         SDL_Surface* intText = TTF_RenderText_Solid(font, Util::toString<int>(storageInt).c_str(),      getCurrentColor());
00319         SDL_Rect r;
00320 
00321         r.x = centerX + INPUT_HORIZ_SPACE;
00322         r.y = centerY - intText->h /2;
00323         r.w = intText->w;
00324         r.h = intText->h;
00325 
00326         SDL_BlitSurface(intText, NULL, surf, &r);
00327         SDL_FreeSurface(intText);
00328 }
00329 
00330 #endif // ifdef HAVE_SDL_TTF
00331 
00332 void KeyMapContainer::init() {
00333         addPair("a",    SDLK_a);
00334         addPair("b",    SDLK_b);
00335         addPair("c",    SDLK_c);
00336         addPair("d",    SDLK_d);
00337         addPair("e",    SDLK_e);
00338         addPair("f",    SDLK_f);
00339         addPair("g",    SDLK_g);
00340         addPair("h",    SDLK_h);
00341         addPair("i",    SDLK_i);
00342         addPair("j",    SDLK_j);
00343         addPair("k",    SDLK_k);
00344         addPair("l",    SDLK_l);
00345         addPair("m",    SDLK_m);
00346         addPair("n",    SDLK_n);
00347         addPair("o",    SDLK_o);
00348         addPair("p",    SDLK_p);
00349         addPair("q",    SDLK_q);
00350         addPair("r",    SDLK_r);
00351         addPair("s",    SDLK_s);
00352         addPair("t",    SDLK_t);
00353         addPair("u",    SDLK_u);
00354         addPair("v",    SDLK_v);
00355         addPair("w",    SDLK_w);
00356         addPair("x",    SDLK_x);
00357         addPair("y",    SDLK_y);
00358         addPair("z",    SDLK_z);
00359 
00360         addPair("0",    SDLK_0);
00361         addPair("1",    SDLK_1);
00362         addPair("2",    SDLK_2);
00363         addPair("3",    SDLK_3);
00364         addPair("4",    SDLK_4);
00365         addPair("5",    SDLK_5);
00366         addPair("6",    SDLK_6);
00367         addPair("7",    SDLK_7);
00368         addPair("8",    SDLK_8);
00369         addPair("9",    SDLK_9);
00370 
00371         addPair("kp0",  SDLK_KP0);
00372         addPair("kp1",  SDLK_KP1);
00373         addPair("kp2",  SDLK_KP2);
00374         addPair("kp3",  SDLK_KP3);
00375         addPair("kp4",  SDLK_KP4);
00376         addPair("kp5",  SDLK_KP5);
00377         addPair("kp6",  SDLK_KP6);
00378         addPair("kp7",  SDLK_KP7);
00379         addPair("kp8",  SDLK_KP8);
00380         addPair("kp9",  SDLK_KP9);
00381 
00382                 addPair("left", SDLK_LEFT);
00383                 addPair("right", SDLK_RIGHT);
00384                 addPair("down", SDLK_DOWN);
00385                 addPair("up",   SDLK_UP);
00386 }
00387 
00388 const StringToKeyMap_t& KeyMapContainer::getStringToKeyMap() {
00389         if (!initialized) init();
00390         return stringKeyMap;
00391 }
00392 
00393 const KeyToStringMap_t& KeyMapContainer::getKeyToStringMap() {
00394         if (!initialized) init();
00395         return keyStringMap;
00396 }
00397 
00398 void KeyMapContainer::addPair(const std::string& s, const SDLKey& k ) {
00399         keyStringMap[k] = s;
00400         stringKeyMap[s] = k;
00401 }
00402 

Generated on Tue May 21 07:26:51 2002 for BomberLAN by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001