////////////////////////////////////////////////////////////////////// // XLogical - A puzzle game // // Copyright (C) 2000 Neil Brown, Tom Warkentin // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // or at the website: http://www.gnu.org // //////////////////////////////////////////////////////////////////////// #include #include "audio.h" #include "exception.h" #include "gamelogic.h" #include "globals.h" #include "menuvertical.h" #include "properties.h" #include "sound_files.h" const int CMenuVertical::kTopOffset = 32; const int CMenuVertical::kBottomOffset = 32; CMenuVertical::CMenuVertical( const string &aString ) : CMenuText( aString ) { #if DEBUG & 1 cout << ">CMenuVertical::CMenuVertical()" << endl; #endif fCurrChildIndex = -1; fManager = true; #if DEBUG & 1 cout << "CMenuVertical::~CMenuVertical()" << endl; #endif #if DEBUG & 1 cout << "CMenuVertical::Click()" << endl; cout << "aX=" << aX << " aY=" << aY << " aButton=" << aButton << endl; #endif if (gTop == this) { if ((aButton == 1) && !fChildren.empty()) { for( int i=0; i < static_cast(fChildren.size()); i++) { if ((aX >= fChildren[i]->X()) && (aX <= fChildren[i]->X() + fChildren[i]->Width()) && (aY >= fChildren[i]->Y()) && (aY <= fChildren[i]->Y() + fChildren[i]->Height()) && fChildren[i]->IsHilightable()) { fChildren[fCurrChildIndex]->SetHilighted( false ); fChildren[i]->SetHilighted( true ); fCurrChildIndex = i; fChildren[i]->Click( aX, aY, aButton ); RepositionChildren(); break; } } } } else { CMenuText::Click( aX, aY, aButton ); } #if DEBUG & 1 cout << "CMenuVertical::Draw()" << endl; #endif if (gTop == this) { Children::iterator iter; for( iter=fChildren.begin(); iter != fChildren.end(); ++iter ) { graphDriver->graph_clear_rect( (*iter)->X(), (*iter)->Y(), (*iter)->Width(), (*iter)->Height() ); (*iter)->Draw(); } } else { graphDriver->graph_clear_rect( X(), Y(), Width(), Height() ); CMenuText::Draw(); } #if DEBUG & 1 cout << "CMenuVertical::Keypress()" << endl; #endif CMenuBase *mgr; switch( aKeyval ) { case eEsc: if ((mgr = gTop->ParentManager())) { mgr->Start( graphDriver->graph_main_width(), graphDriver->graph_main_height() ); } else { if (fRestoreFunc) { (*fRestoreFunc)(); } } break; case eEnter: Selected(); break; case eUp: if (!fChildren.empty()) { int i = fCurrChildIndex; audioDriver->play_sound( soundFiles[SOUND_MENU_CLICK] ); fChildren[fCurrChildIndex]->SetHilighted( false ); if (fCurrChildIndex > 0) { i--; } else { i = fChildren.size() - 1; } i = PrevHilightableChild( i ); if (i != -1) { fCurrChildIndex = i; } fChildren[fCurrChildIndex]->SetHilighted( true ); RepositionChildren(); } break; case eDown: if (!fChildren.empty()) { int i = fCurrChildIndex; audioDriver->play_sound( soundFiles[SOUND_MENU_CLICK] ); fChildren[fCurrChildIndex]->SetHilighted( false ); if (fCurrChildIndex < static_cast(fChildren.size())-1) { i++; } else { i = 0; } i = NextHilightableChild( i ); if (i != -1) { fCurrChildIndex = i; } fChildren[fCurrChildIndex]->SetHilighted( true ); RepositionChildren(); } break; default: fChildren[fCurrChildIndex]->Keypress( aKeyval ); break; } #if DEBUG & 1 cout << "CMenuVertical::Manage()" << endl; #endif if (gTop == this) { if ((!fChildren.empty()) && (fCurrChildIndex == -1)) { fCurrChildIndex = NextHilightableChild( 0 ); if (fCurrChildIndex != -1) { fChildren[fCurrChildIndex]->SetHilighted( true ); } } int x, y; if (Height() < (fMainHeight - kTopOffset - kBottomOffset)) { x = (fMainWidth/2) - (Width()/2); y = (fMainHeight/2) - (Height()/2); SetPos( x, y ); for( int i=0, y=0; i(fChildren.size()); i++ ) { fChildren[i]->SetPos( fX + (fWidth / 2) - (fChildren[i]->Width() / 2), fY + y ); fChildren[i]->Manage(); y += fChildren[i]->Height(); } } else { RepositionChildren(); } } else { CMenuText::Manage(); } #if DEBUG & 1 cout << "(fChildren.size()); i+=1 ) { if (fChildren[i]->IsHilightable()) { return( i ); } } return( -1 ); } int CMenuVertical::PrevHilightableChild( int aChildIndex ) { for( int i=aChildIndex; i>=0; i-=1 ) { if (fChildren[i]->IsHilightable()) { return( i ); } } return( -1 ); } void CMenuVertical::Realize( void ) { #if DEBUG & 1 cout << ">CMenuVertical::Realize()" << endl; #endif if (gTop == this) { Children::iterator iter; fHeight = 0; fWidth = 0; for(iter=CMenuBase::fChildren.begin(); iter != CMenuBase::fChildren.end(); ++iter ) { (*iter)->Realize(); if ((*iter)->Width() > fWidth) { fWidth = (*iter)->Width(); } fHeight += (*iter)->Height(); } } else { CMenuText::Realize(); } #if DEBUG & 1 cout << "CMenuVertical::RepositionChildren()" << endl; #endif if ((Height() > (fMainHeight - kTopOffset - kBottomOffset)) && !fChildren.empty()) { int i, y; y = fMainHeight/2 - fChildren[fCurrChildIndex]->Height()/2; fChildren[fCurrChildIndex]->SetPos( fMainWidth/2 - fChildren[fCurrChildIndex]->Width()/2, y ); for(i=fCurrChildIndex-1; i>=0; i-- ) { y -= fChildren[i]->Height(); fChildren[i]->SetPos( fMainWidth/2 - fChildren[i]->Width()/2, y ); } for(i=fCurrChildIndex+1, y=fMainHeight/2 + fChildren[fCurrChildIndex]->Height()/2; i(fChildren.size()); i++ ) { fChildren[i]->SetPos( fMainWidth/2 - fChildren[i]->Width()/2, y ); y += fChildren[i]->Height(); } } #if DEBUG & 1 cout << "CMenuVertical::Selected()" << endl; #endif if (gTop == this) { if (fCurrChildIndex >= 0) { fChildren[fCurrChildIndex]->Selected(); } } else { Start( graphDriver->graph_main_width(), graphDriver->graph_main_height(), ParentManager()->DrawFunc(), ParentManager()->RestoreFunc() ); } #if DEBUG & 1 cout << "