home *** CD-ROM | disk | FTP | other *** search
- #include "Menu.h"
-
- #include "Gui.h"
-
- #include "Input.h"
- #include "texfont.h"
- #include "SoundInfo.h"
- //#include "Sound.h"
- #include "Renderer.h"
- #include "ConsoleFrontEnd.h"
- #include "System.h"
- #include "Display.h"
-
- #define MENU_FONT_SCALE ( 0.5f )
-
-
- Mix_Chunk* Menu::pressButtonSound = NULL;
- Mix_Chunk* Menu::toggleSound = NULL;
- Mix_Chunk* Menu::errorSound = NULL;
-
-
- MenuItem::MenuItem(int x, int y, int width, int height){
- this->x = x;
- this->y = y;
- this->width = width;
- this->height = height;
-
- highlighted=false;
- hasKeyboardFocus = false;
- active=true;
- }
-
- MenuItem::~MenuItem(){
- }
-
- void MenuItem::activate(){
- active=true;
- }
-
- void MenuItem::deactivate(){
- active=false;
- }
-
- bool MenuItem::isActive(){
- return active;
- }
-
- void MenuItem::draw(){
- }
-
- void MenuItem::clicked(){
- }
-
- void MenuItem::clickedRight(){
- }
-
- void MenuItem::receiveKey(SDL_keysym* keysym){
- }
-
-
- TextButton::TextButton(int x, int y, int width, int height, const char* label):MenuItem(x,y,width, height){
- this->label = label;
-
- callback=NULL;
- }
-
- TextButton::TextButton(int x, int y, const char* label):MenuItem(0,0,0,0){
- this->x = x;
- this->y = y;
- this->label = label;
-
- width = (int)(getStringWidth(Gui::info.var.menu_bigFont, label)*MENU_FONT_SCALE);
- height = (int)(Gui::info.var.menu_bigFont->height*MENU_FONT_SCALE);
-
- callback=NULL;
- }
-
- TextButton::~TextButton(){
- }
-
- void TextButton::draw(){
- if(active){
- if(!highlighted)
- glColor4fv(Gui::info.var.menu_normalColor);
- else
- glColor4fv(Gui::info.var.menu_activeColor);
- }else{
- glColor4fv(Gui::info.var.menu_passiveColor);
- }
-
- glBegin(GL_LINE_LOOP);
- glVertex2i(x, y);
- glVertex2i(x+width, y);
- glVertex2i(x+width, y+height);
- glVertex2i(x, y+height);
- glEnd();
-
- //drawScaledAndAlignedString(MENU_POS_SCALE_X(x+width/2), MENU_POS_SCALE_Y(y), labelScaleX, labelScaleY, Gui::info.var.menu_bigFont, TEXT_ALIGN_CENTER, label);
- drawScaledAndAlignedString(x+width/2, y, MENU_FONT_SCALE, MENU_FONT_SCALE, Gui::info.var.menu_bigFont, TEXT_ALIGN_CENTER, label);
- }
-
- void TextButton::clicked(){
- if(Sound::info.var.enabled && Sound::info.var.playSamples)
- Sound::playSample(SOUND_COMPUTER_CHANNEL, Menu::pressButtonSound);
-
- if(callback!=NULL)
- callback();
- }
-
- void TextButton::clickedRight(){
- clicked();
- }
-
- void TextButton::setCallbackFunction(void (*func)(void)){
- callback=func;
- }
-
-
-
-
-
-
-
- ToggleButton::ToggleButton(int x, int y, const char** items, int numItems, const char* label):MenuItem(x, y, 0, 0){
- this->width = (int)(getStringWidth(Gui::info.var.menu_smallFont, label)*1.0f);
- this->height = (int)(Gui::info.var.menu_smallFont->height*1.0f);
- this->label = label;
-
- this->items = items;
- this->numItems = numItems;
- this->index = 0;
-
- int maxWidth = 0;
- for(int i = 0; i < numItems; i++){
- int w = (int)( getStringWidth(Gui::info.var.menu_smallFont, items[i])*1.0f );
- maxWidth = w > maxWidth ? w : maxWidth;
- //printf("string %i: %s\n", i, items[i]);
- }
- this->width += maxWidth;
- }
-
-
- ToggleButton::~ToggleButton(){
- }
-
- void ToggleButton::draw(){
- if(active){
- if(!highlighted)
- glColor4fv(Gui::info.var.menu_normalColor);
- else
- glColor4fv(Gui::info.var.menu_activeColor);
- }else{
- glColor4fv(Gui::info.var.menu_passiveColor);
- }
-
- drawScaledFormatString(x,y,1.0f, 1.0f,Gui::info.var.menu_smallFont, "%s%s", label, items[index]);
- }
-
- void ToggleButton::clicked(){
- if(Sound::info.var.enabled && Sound::info.var.playSamples)
- Sound::playSample(SOUND_COMPUTER_CHANNEL, Menu::toggleSound);
-
- index = (index+1) % numItems;
- }
-
- void ToggleButton::clickedRight(){
- if(Sound::info.var.enabled && Sound::info.var.playSamples)
- Sound::playSample(SOUND_COMPUTER_CHANNEL, Menu::toggleSound);
-
- index = (index-1) < 0 ? numItems-1 : (index-1);
- }
-
- const char* ToggleButton::getSelectedItem(){
- return items[index];
- }
- int ToggleButton::getIndex(){
- return index;
- }
- void ToggleButton::setIndex(int newIndex){
- if(newIndex >= 0 && newIndex < numItems){
- this->index = newIndex;
- }
- }
-
- void ToggleButton::changeItems(const char** newItems, int newNumItems){
- this->items = newItems;
- this->numItems = newNumItems;
- this->index = 0;
-
- int maxWidth = 0;
- for(int i = 0; i < numItems; i++){
- int w = (int)( getStringWidth(Gui::info.var.menu_smallFont, items[i])*1.0f );
- maxWidth = w > maxWidth ? w : maxWidth;
- //printf("string %i: %s\n", i, items[i]);
- }
- this->width = (int)( getStringWidth(Gui::info.var.menu_smallFont, label)*1.0f + maxWidth );
- }
-
-
-
-
-
-
-
-
-
-
- Textfield::Textfield(int x, int y, int minChars, int maxChars, const char* label):MenuItem(x, y, 0, 0){
- this->width = (int)(getStringWidth(Gui::info.var.menu_smallFont, label)*1.0f);
- this->height = (int)(Gui::info.var.menu_smallFont->height*1.0f);
- this->label = label;
-
- this->minChars = minChars;
- this->maxChars = maxChars;
-
- this->inputStrIndex = 0;
- this->inputStr[0] = '\0';
- }
-
-
- Textfield::~Textfield(){
- }
-
- void Textfield::draw(){
- if(active){
- if(!highlighted)
- glColor4fv(Gui::info.var.menu_normalColor);
- else
- glColor4fv(Gui::info.var.menu_activeColor);
- }else{
- glColor4fv(Gui::info.var.menu_passiveColor);
- }
-
- if(hasKeyboardFocus){
- drawScaledFormatString(x,y,1.0f, 1.0f,Gui::info.var.menu_smallFont, "%s%s", label, inputStr);
- if((SDL_GetTicks()/500)%2){
- char buff[CON_MAX_STRING_LENGTH];
- strncpy(buff, inputStr, inputStrIndex);
- buff[inputStrIndex] = '\0';
- float xOffs = (getStringWidth(Gui::info.var.menu_smallFont, label)+getStringWidth(Gui::info.var.menu_smallFont, buff))*1.0f;
- drawScaledString(x+(int)xOffs, y, 1.0f, 1.0f, Gui::info.var.menu_smallFont, "_");
- }
- }else{
- drawScaledFormatString(x,y,1.0f, 1.0f,Gui::info.var.menu_smallFont, "%s%s", label, text);
- }
-
- this->width = (int)( getStringWidth(Gui::info.var.menu_smallFont, label) + getStringWidth(Gui::info.var.menu_smallFont, text)*1.0f );
- }
-
- void Textfield::clicked(){
- if(Sound::info.var.enabled && Sound::info.var.playSamples)
- Sound::playSample(SOUND_COMPUTER_CHANNEL, Menu::toggleSound);
-
- strcpy(inputStr, text);
- inputStrIndex = strlen(inputStr);
- SDL_EnableUNICODE(1);
- SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
- // hasKeyboardFocus = true;
- }
-
- void Textfield::clickedRight(){
- }
-
-
- void Textfield::receiveKey(SDL_keysym* keysym){
- int i;
- SDLKey key=keysym->sym;
-
- if(key==SDLK_ESCAPE){
- //deactivate();
- strcpy(inputStr, text);
- hasKeyboardFocus = false;
- SDL_EnableUNICODE(0);
- SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
- }else if(key==SDLK_RIGHT){
- if(inputStr[inputStrIndex]!='\0'){
- inputStrIndex++;
- }
- }else if(key==SDLK_LEFT){
- if(inputStrIndex>0){
- inputStrIndex--;
- }
- }else if(key==SDLK_HOME && !(keysym->mod & KMOD_CTRL) ){
- inputStrIndex=0;
- }else if(key==SDLK_END && !(keysym->mod & KMOD_CTRL) ){
- inputStrIndex=strlen(inputStr);
- }else if(key==SDLK_RETURN){ // enter
- // tja...
- // inputStr[inputStrIndex] = '\0';
- if(strlen(inputStr) >= (unsigned int)minChars && strlen(inputStr) <= (unsigned int)maxChars){
- strcpy(text, inputStr);
- }else{
- strcpy(inputStr, text);
- }
- hasKeyboardFocus = false;
- SDL_EnableUNICODE(0);
- SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
- }else if(key==SDLK_BACKSPACE){ // backspace
- if(inputStrIndex<=0)
- return;
-
- i=inputStrIndex-1;
- while(inputStr[i]!='\0'){
- inputStr[i]=inputStr[i+1];
- i++;
- }
- inputStrIndex-=1;
- }else if(key==SDLK_DELETE){ // del
- if(inputStr[inputStrIndex]=='\0')
- return;
-
- i=inputStrIndex;
- while(inputStr[i]!='\0'){
- inputStr[i]=inputStr[i+1];
- i++;
- }
- }else{ // add char to inputStr
- int l=strlen(inputStr);
- if(l < CON_MAX_STRING_LENGTH && l < maxChars){
- char ch;
- if ( (keysym->unicode & 0xFF80) == 0 && keysym->unicode!=0) {
- ch = keysym->unicode & 0x7F;
- for(i=l+1;i>inputStrIndex;i--){
- inputStr[i]=inputStr[i-1];
- }
-
- inputStr[inputStrIndex]=ch;
- inputStrIndex++;
- //inputStr[inputStrIndex]='\0';
- //inputStrIndex = inputStrIndex >= CON_MAX_LINE_LENGTH-1 ? CON_MAX_LINE_LENGTH-1 : inputStrIndex+1;
- }else{
- // warn("(in ConsoleFrontEnd::recieveKey()): unicode of key not known!\n\n");
- }
- }
- }
-
- }
-
- char* Textfield::getText(){
- return text;
- }
-
- void Textfield::setText(const char* newText){
- if(strlen(newText) >= (unsigned int)minChars && strlen(newText) <= (unsigned int)maxChars)
- strcpy(this->text, newText);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Menu::Menu(const char* name){
- int i;
-
- this->name=name;
-
- for(i=0;i<MENU_MAX_SUBMENUS;i++){
- submenus[i]=NULL;
- }
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- menuItems[i]=NULL;
- }
-
- opened=false;
- allowConsole=false;
- }
-
- Menu::~Menu(){
- int i;
- /*
- for(i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]!=NULL)
- delete submenus[i];
- }
- */
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]!=NULL)
- delete menuItems[i];
- }
-
- }
-
- MenuItem* Menu::getMenuItem(int x, int y){
- int i;
-
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]!=NULL
- && y>menuItems[i]->y && y<menuItems[i]->y+menuItems[i]->height && x>menuItems[i]->x && x<menuItems[i]->x+menuItems[i]->width){
- return menuItems[i];
- }
- }
-
- return NULL;
- }
-
- bool Menu::addMenuItem(MenuItem* item){
- int i;
-
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]==NULL){
- menuItems[i]=item;
- return true;
- }
- }
-
- return false;
- }
-
- bool Menu::removeMenuItem(MenuItem* item){
- int i;
-
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]==item){
- menuItems[i]=NULL;
- return true;
- }
- }
-
- return false;
- }
-
- bool Menu::deleteMenuItem(MenuItem* item){
- int i;
-
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]==item){
- delete menuItems[i];
- menuItems[i]=NULL;
- return true;
- }
- }
-
- return false;
- }
-
- bool Menu::addSubmenu(Menu* submenu){
- int i;
-
- for(i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]==NULL){
- submenus[i]=submenu;
- return true;
- }
- }
-
- return false;
- }
-
- bool Menu::removeSubmenu(Menu* submenu){
- int i;
-
- for(i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]==submenu){
- submenus[i]=NULL;
- return true;
- }
- }
-
- return false;
- }
-
- bool Menu::deleteSubmenu(Menu* submenu){
- int i;
-
- for(i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]==submenu){
- delete submenus[i];
- submenus[i]=NULL;
- return true;
- }
- }
-
- return false;
- }
-
- void Menu::closeAllSubmenus(){
- for(int i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]!=NULL && submenus[i]->isOpened()){
- submenus[i]->close();
- }
- }
- }
-
- /*
- bool Menu::openAsSubmenu(){
- if(!opened){
- opened=true;
- //mainLoop();
- return true;
- }else{
- return false;
- }
- }
- */
- bool Menu::open(){
- if(!opened){
- opened=true;
- //showMouseCursor(); // THINKABOUTME
- //freeInput();
- //mainLoop();
- return true;
- }else{
- return false;
- }
- }
-
- bool Menu::close(){
- if(opened){
- /* for(int i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]!=NULL && submenus[i]->isOpened())
- submenus[i]->closeAsSubmenu();
- }
- */
- closeAllSubmenus();
- opened=false;
- //hideMouseCursor();
- //grabInput();
- return true;
- }else{
- return false;
- }
- }
- /*
- bool Menu::closeAsSubmenu(){
- if(opened){
- for(int i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]!=NULL && submenus[i]->isOpened())
- submenus[i]->closeAsSubmenu();
- }
- opened=false;
- return true;
- }else{
- return false;
- }
- }
- */
- bool Menu::isOpened(){
- return opened;
- }
-
- void Menu::mainLoop(){
- SDL_Event event;
-
- while(opened){
- while( SDL_PollEvent(& event) ){
- switch(event.type)
- {
- case SDL_QUIT:
- System::normalQuit();
- break;
-
- case SDL_KEYDOWN:
- handleKeyboardEvent(&event.key);
- break;
-
- case SDL_KEYUP:
- handleKeyboardEvent(&event.key);
- break;
-
- case SDL_MOUSEMOTION:
- handleMouseMotionEvent(&event.motion);
- break;
-
- case SDL_MOUSEBUTTONDOWN:
- handleMouseButtonEvent(&event.button);
- break;
-
- case SDL_MOUSEBUTTONUP:
- handleMouseButtonEvent(&event.button);
- break;
-
- default:
- break;
- } // switch
- } // while( SDL_ ...
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- draw();
- if(allowConsole && consoleFrontEnd->isActive){
- consoleFrontEnd->draw();
- }
- SDL_GL_SwapBuffers(); // THINKABOUTME: spΣter backgroundScene
- } // while( ! done)
-
- }
-
- void Menu::draw(){
- int i;
-
- Renderer::beginDrawing();
-
- drawBackground();
-
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]!=NULL){
- menuItems[i]->draw();
- }
- }
-
- Renderer::endDrawing();
-
-
- for(i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]!=NULL && submenus[i]->isOpened()){
- submenus[i]->draw();
- }
- }
- }
-
- void Menu::drawBackground(){
- int i;
- int x=800;
- int y=600;
- int mx=0;
- int my=0;
-
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]!=NULL){
- x = x<menuItems[i]->x ? x : menuItems[i]->x;
- y = y<menuItems[i]->y ? y : menuItems[i]->y;
-
- mx = mx>menuItems[i]->x+menuItems[i]->width ? mx : menuItems[i]->x+menuItems[i]->width;
- my = my>menuItems[i]->y+menuItems[i]->height ? my : menuItems[i]->y+menuItems[i]->height;
- }
- }
-
- if(x>=800 || y>=600 || mx<=0 || my<=0)
- return;
-
- x -= 10;
- y -= 10;
- mx += 10;
- my += 10;
-
- Renderer::drawQuad(x, y, mx, my, Gui::info.var.menu_normalColor, Gui::info.var.menu_backgroundColor);
- }
-
-
- void Menu::handleKeyboardEvent(SDL_KeyboardEvent* event){
- int i;
-
- if(allowConsole && event->type==SDL_KEYDOWN){
- if(Input::keyMap[event->keysym.sym].action==TOGGLE_CONSOLE){
- if(consoleFrontEnd->isActive)
- consoleFrontEnd->deactivate();
- else
- consoleFrontEnd->activate();
-
- return;
- }
- if(consoleFrontEnd->isActive){
- consoleFrontEnd->receiveKey(&event->keysym);
- return;
- }
- }
-
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]!=NULL && menuItems[i]->hasKeyboardFocus && event->type==SDL_KEYDOWN)
- menuItems[i]->receiveKey(&event->keysym);
- }
-
-
- for(i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]!=NULL && submenus[i]->isOpened())
- submenus[i]->handleKeyboardEvent(event);
- }
- // printf("sym: %d, scancode: %d, unicode: %d, mod: %d\n",keysym->sym, keysym->scancode, keysym->unicode, keysym->mod);
- }
-
- void Menu::handleMouseMotionEvent(SDL_MouseMotionEvent* event){
- // printf("MOUSE MOTION: x: %i, y: %i\n", event->x, event->y);
- int i;
-
- // THINKABOUTME: hightlights??
- for(i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i]!=NULL)
- menuItems[i]->highlighted=false;
- }
- MenuItem* mi = getMenuItem((int)(event->x/Display::info.var.scaleX), (int)((Display::info.var.height - event->y)/Display::info.var.scaleY));
- if(mi!=NULL)
- mi->highlighted=true;
-
- for(i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]!=NULL && submenus[i]->isOpened())
- submenus[i]->handleMouseMotionEvent(event);
- }
-
- }
-
- void Menu::handleMouseButtonEvent(SDL_MouseButtonEvent* event){
- // printf("MOUSE BUTTON: %i\n", event->button);
- if(allowConsole && consoleFrontEnd->isActive)
- return;
-
- int button=event->button;
- if(button != MOUSE_BUTTON1 && button != MOUSE_BUTTON3)
- return;
-
- if(event->type==SDL_MOUSEBUTTONUP){
- MenuItem* mi = getMenuItem((int)(event->x/Display::info.var.scaleX), (int)((Display::info.var.height - event->y)/Display::info.var.scaleY));
-
- if(mi!=NULL && mi->isActive()){
- for(int i=0;i<MENU_MAX_MENU_ITEMS;i++){
- if(menuItems[i] != NULL)
- menuItems[i]->hasKeyboardFocus = false;
- }
- mi->hasKeyboardFocus = true;
-
- if(button == MOUSE_BUTTON1){
- mi->clicked();
- }else if(button == MOUSE_BUTTON3){
- mi->clickedRight();
- }
- }
- }else if(event->type==SDL_MOUSEBUTTONDOWN){
- // THINKABOUTME: play a sound??
- }
-
- for(int i=0;i<MENU_MAX_SUBMENUS;i++){
- if(submenus[i]!=NULL && submenus[i]->isOpened())
- submenus[i]->handleMouseButtonEvent(event);
- }
- }
-
-
-