////////////////////////////////////////////////////////////////////// // 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 // //////////////////////////////////////////////////////////////////////// // Language Includes #include #include // Application Includes #include "audio.h" #include "exception.h" #include "gamelogic.h" #include "globals.h" #include "graph.h" #include "menubase.h" #include "properties.h" #include "sound_files.h" class CMenuBase *CMenuBase::gTop = NULL; int CMenuBase::fMainHeight = 0; int CMenuBase::fMainWidth = 0; CMenuBase::CMenuBase( void ) : fHilightable( true ), fHilighted( false ), fManager( false ), fParent( NULL ), fHeight( 0 ), fWidth( 0 ), fX( 0 ), fY( 0 ), fDrawFunc( NULL ), fRestoreFunc( NULL ) { #if DEBUG & 1 cout << ">CMenuBase::CMenuBase()" << endl; #endif #if DEBUG & 1 cout << "CMenuBase::~CMenuBase()" << endl; #endif Children::iterator iter; // free all the children for( iter=fChildren.begin(); iter != fChildren.end(); ++iter ) { delete (*iter); } fChildren.clear(); // check if we are destroying the root if (gTop == this) { gTop = NULL; } #if DEBUG & 1 cout << "CMenuBase::AddChild()" << endl; #endif if (aChild == this) { ThrowEx( "cannot be a parent of oneself" ); } if (aChild->fParent != NULL) { ThrowEx( "child already has a parent" ); } aChild->fParent = this; fChildren.push_back( aChild ); #if DEBUG & 1 cout << "CMenuBase::ChildManager()" << endl; #endif Children::iterator iter; for( iter=fChildren.begin(); iter!=fChildren.end(); ++iter) { if ((*iter)->IsManager()) { return( *iter ); } } #if DEBUG & 1 cout << "CMenuBase::Click()" << endl; cout << "aX=" << aX << " aY=" << aY << " aButton=" << aButton << endl; #endif #if DEBUG & 1 cout << "CMenuBase::HandleClick()" << endl; cout << "aX=" << aX << " aY=" << aY << " aButton=" << aButton << endl; #endif if (gTop == NULL) { ThrowEx( "CMenuBase::gTop not set" ); } gTop->Click( aX, aY, aButton ); #if DEBUG & 1 cout << "CMenuBase::HandleLoop()" << endl; #endif if (gTop == NULL) { ThrowEx( "CMenuBase::gTop not set" ); } graphDriver->graph_clear_rect( 0, 0, fMainWidth, fMainHeight ); gTop->Draw(); #if DEBUG & 1 cout << "CMenuBase::HandleKeyPress()" << endl; cout << "aKeyVal=" << static_cast( aKeyval ) << endl; #endif if (gTop == NULL) { ThrowEx( "CMenuBase::gTop not set" ); } gTop->Keypress( aKeyval ); #if DEBUG & 1 cout << "CMenuBase::Height()" << endl; #endif #if DEBUG & 1 cout << "CMenuBase::Keypress()" << endl; cout << "aKeyVal=" << static_cast( aKeyval ) << endl; #endif #if DEBUG & 1 cout << "CMenuBase::Manage()" << endl; #endif #if DEBUG & 1 cout << "CMenuBase::ParentManager()" << endl; #endif CMenuBase *tmp = fParent; while( tmp && !tmp->IsManager() ) { tmp = tmp->Parent(); } #if DEBUG & 1 cout << "CMenuBase::SetHilighted()" << endl; #endif if (fHilightable) { fHilighted = aHilighted; } #if DEBUG & 1 cout << "CMenuBase::SetPos()" << endl; cout << "aX=" << aX << " aY=" << aY << endl; #endif fX = aX; fY = aY; #if DEBUG & 1 cout << "CMenuBase::Start()" << endl; #endif gTop = this; audioDriver->play_sound( soundFiles[SOUND_MENU_CLICK] ); // calculate size of menu item(s) Realize(); // calculate initial starting position fMainWidth = aWidth; fMainHeight = aHeight; if (aDrawFunc) { fDrawFunc = aDrawFunc; } if (aRestoreFunc) { fRestoreFunc = aRestoreFunc; } // set graphics callbacks for menu graphDriver->graph_set_click_func( HandleClick ); graphDriver->graph_set_key_press_func( HandleKeyPress ); graphDriver->graph_set_loop_func( HandleLoop ); // calculate position of children Manage(); if (fDrawFunc) { fDrawFunc(); graphDriver->graph_clear_rect( 0, 0, fMainWidth, fMainHeight ); Draw(); } #if DEBUG & 1 cout << "CMenuBase::Width()" << endl; #endif #if DEBUG & 1 cout << "