DOOM-3-BFG

DOOM 3 BFG Edition
Log | Files | Refs

MenuHandler_PDA.cpp (20246B)


      1 /*
      2 ===========================================================================
      3 
      4 Doom 3 BFG Edition GPL Source Code
      5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 
      6 
      7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").  
      8 
      9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
     10 it under the terms of the GNU General Public License as published by
     11 the Free Software Foundation, either version 3 of the License, or
     12 (at your option) any later version.
     13 
     14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
     15 but WITHOUT ANY WARRANTY; without even the implied warranty of
     16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     17 GNU General Public License for more details.
     18 
     19 You should have received a copy of the GNU General Public License
     20 along with Doom 3 BFG Edition Source Code.  If not, see <http://www.gnu.org/licenses/>.
     21 
     22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code.  If not, please request a copy in writing from id Software at the address below.
     23 
     24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
     25 
     26 ===========================================================================
     27 */
     28 #pragma hdrstop
     29 #include "../../idLib/precompiled.h"
     30 #include "../Game_local.h"
     31 
     32 static const int MAX_PDA_ITEMS = 15;
     33 static const int MAX_NAV_OPTIONS = 4;
     34 
     35 /*
     36 ========================
     37 idMenuHandler_PDA::Update
     38 ========================
     39 */
     40 void idMenuHandler_PDA::Update() {
     41 
     42 	if ( gui == NULL || !gui->IsActive() ) {
     43 		return;
     44 	}
     45 	
     46 	if ( activeScreen != nextScreen ) {
     47 
     48 		if ( nextScreen == PDA_AREA_INVALID ) {
     49 			menuScreens[ activeScreen ]->HideScreen( static_cast<mainMenuTransition_t>(transition) );
     50 			
     51 			idMenuWidget_CommandBar * cmdBar = dynamic_cast< idMenuWidget_CommandBar * >( GetChildFromIndex( PDA_WIDGET_CMD_BAR ) );
     52 			if ( cmdBar != NULL ) {
     53 				cmdBar->ClearAllButtons();
     54 				cmdBar->Update();
     55 			}
     56 
     57 			idSWFSpriteInstance * menu = gui->GetRootObject().GetNestedSprite( "navBar" );
     58 			idSWFSpriteInstance * bg = gui->GetRootObject().GetNestedSprite( "background" );
     59 			idSWFSpriteInstance * edging = gui->GetRootObject().GetNestedSprite( "_fullScreen" );
     60 
     61 			if ( menu != NULL ) {
     62 				menu->PlayFrame( "rollOff" );
     63 			}
     64 
     65 			if ( bg != NULL ) {
     66 				bg->PlayFrame( "rollOff" );
     67 			}
     68 
     69 			if ( edging != NULL ) {
     70 				edging->PlayFrame( "rollOff" );
     71 			}
     72 
     73 		} else {		
     74 			if ( activeScreen > PDA_AREA_INVALID && activeScreen < PDA_NUM_AREAS && menuScreens[ activeScreen ] != NULL ) {
     75 				menuScreens[ activeScreen ]->HideScreen( static_cast<mainMenuTransition_t>(transition) );
     76 			}
     77 
     78 			if ( nextScreen > PDA_AREA_INVALID && nextScreen < PDA_NUM_AREAS && menuScreens[ nextScreen ] != NULL ) {
     79 				menuScreens[ nextScreen ]->UpdateCmds();
     80 				menuScreens[ nextScreen ]->ShowScreen( static_cast<mainMenuTransition_t>(transition) );			
     81 			}
     82 		}
     83 
     84 		transition = MENU_TRANSITION_INVALID;
     85 		activeScreen = nextScreen;
     86 	}
     87 
     88 	idPlayer * player = gameLocal.GetLocalPlayer();
     89 	if ( player != NULL ) {
     90 		if ( activeScreen == PDA_AREA_USER_DATA ) {
     91 			bool isPlaying = player->IsSoundChannelPlaying( SND_CHANNEL_PDA_AUDIO );
     92 			UpdateAudioLogPlaying( isPlaying );
     93 		}
     94 
     95 		if ( activeScreen == PDA_AREA_VIDEO_DISKS ) {
     96 			bool isPlaying = player->IsSoundChannelPlaying( SND_CHANNEL_PDA_VIDEO );
     97 			UdpateVideoPlaying( isPlaying );
     98 		}
     99 	}
    100 
    101 	idMenuHandler::Update();
    102 }
    103 
    104 /*
    105 ================================================
    106 idMenuHandler::TriggerMenu
    107 ================================================
    108 */
    109 void idMenuHandler_PDA::TriggerMenu() {
    110 	nextScreen = PDA_AREA_USER_DATA;
    111 	transition = MENU_TRANSITION_FORCE;
    112 }
    113 
    114 /*
    115 ========================
    116 idMenuHandler_PDA::ActivateMenu
    117 ========================
    118 */
    119 void idMenuHandler_PDA::ActivateMenu( bool show ) {
    120 	idMenuHandler::ActivateMenu( show );
    121 
    122 	if ( show ) {
    123 		// Add names to pda
    124 		idPlayer * player = gameLocal.GetLocalPlayer();
    125 		if ( player == NULL ) {	
    126 			return;
    127 		}
    128 
    129 		pdaNames.Clear();
    130 		for ( int j = 0; j < player->GetInventory().pdas.Num(); j++ ) {		
    131 			const idDeclPDA * pda = player->GetInventory().pdas[ j ];
    132 			idList< idStr > names;
    133 			names.Append( pda->GetPdaName() );	
    134 			pdaNames.Append( names );
    135 		}	
    136 		idMenuWidget_DynamicList * pdaList = dynamic_cast< idMenuWidget_DynamicList * >( GetChildFromIndex( PDA_WIDGET_PDA_LIST ) );
    137 		if ( pdaList != NULL ) {
    138 			pdaList->SetListData( pdaNames );
    139 		}
    140 
    141 		navOptions.Clear();
    142 		navOptions.Append( idLocalization::GetString( "#str_04190" ) );
    143 		navOptions.Append( idLocalization::GetString( "#str_01442" ) );
    144 		navOptions.Append( idLocalization::GetString( "#str_01440" ) );
    145 		navOptions.Append( idLocalization::GetString( "#str_01414" ) );
    146 		idMenuWidget_NavBar * navBar = dynamic_cast< idMenuWidget_NavBar * >( GetChildFromIndex( PDA_WIDGET_NAV_BAR ) );
    147 		if ( navBar != NULL ) {
    148 			navBar->SetListHeadings( navOptions );
    149 			navBar->SetFocusIndex( 0 );			
    150 			navBar->Update();
    151 		}
    152 
    153 		idMenuWidget_CommandBar * cmdBar = dynamic_cast< idMenuWidget_CommandBar * >( GetChildFromIndex( PDA_WIDGET_CMD_BAR ) );
    154 		if ( cmdBar != NULL ) {
    155 			cmdBar->ClearAllButtons();
    156 			cmdBar->Update();
    157 		}
    158 
    159 	} else {
    160 		nextScreen = PDA_AREA_INVALID;
    161 		activeScreen = PDA_AREA_INVALID;
    162 	}
    163 
    164 }
    165 
    166 /*
    167 ========================
    168 idMenuHandler_PDA::Initialize
    169 ========================
    170 */
    171 void idMenuHandler_PDA::Initialize( const char * swfFile, idSoundWorld * sw ) {
    172 	idMenuHandler::Initialize( swfFile, sw );
    173 
    174 	//---------------------
    175 	// Initialize the menus
    176 	//---------------------
    177 #define BIND_PDA_SCREEN( screenId, className, menuHandler )				\
    178 	menuScreens[ (screenId) ] = new (TAG_SWF) className();	\
    179 	menuScreens[ (screenId) ]->Initialize( menuHandler ); \
    180 	menuScreens[ (screenId) ]->AddRef(); \
    181 	menuScreens[ (screenId) ]->SetNoAutoFree( true );
    182 
    183 	for ( int i = 0; i < PDA_NUM_AREAS; ++i ) {
    184 		menuScreens[ i ] = NULL;
    185 	}
    186 
    187 	BIND_PDA_SCREEN( PDA_AREA_USER_DATA, idMenuScreen_PDA_UserData, this );
    188 	BIND_PDA_SCREEN( PDA_AREA_USER_EMAIL, idMenuScreen_PDA_UserEmails, this );
    189 	BIND_PDA_SCREEN( PDA_AREA_VIDEO_DISKS, idMenuScreen_PDA_VideoDisks, this );
    190 	BIND_PDA_SCREEN( PDA_AREA_INVENTORY, idMenuScreen_PDA_Inventory, this );
    191 
    192 
    193 	pdaScrollBar.SetSpritePath( "pda_persons", "info", "scrollbar" );
    194 	pdaScrollBar.Initialize( this );
    195 	pdaScrollBar.SetNoAutoFree( true );
    196 
    197 	pdaList.SetSpritePath( "pda_persons", "info", "list" );
    198 	pdaList.SetNumVisibleOptions( MAX_PDA_ITEMS );
    199 	pdaList.SetWrappingAllowed( true );
    200 	pdaList.SetNoAutoFree( true );
    201 
    202 	while ( pdaList.GetChildren().Num() < MAX_PDA_ITEMS ) {
    203 		idMenuWidget_Button * const buttonWidget = new (TAG_SWF) idMenuWidget_Button();
    204 		buttonWidget->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PDA_SELECT_USER, pdaList.GetChildren().Num() );
    205 		buttonWidget->Initialize( this );
    206 		if ( menuScreens[ PDA_AREA_USER_DATA ] != NULL ) {
    207 			idMenuScreen_PDA_UserData * userDataScreen = dynamic_cast< idMenuScreen_PDA_UserData * >( menuScreens[ PDA_AREA_USER_DATA ] );
    208 			if ( userDataScreen != NULL ) {
    209 				buttonWidget->RegisterEventObserver( userDataScreen->GetUserData() );
    210 				buttonWidget->RegisterEventObserver( userDataScreen->GetObjective() );
    211 				buttonWidget->RegisterEventObserver( userDataScreen->GetAudioFiles() );
    212 			}
    213 		}
    214 		if ( menuScreens[ PDA_AREA_USER_EMAIL ] != NULL ) {
    215 			idMenuScreen_PDA_UserEmails * userEmailScreen = dynamic_cast< idMenuScreen_PDA_UserEmails * >( menuScreens[ PDA_AREA_USER_EMAIL ] );
    216 			if ( userEmailScreen != NULL ) {
    217 				buttonWidget->RegisterEventObserver( &userEmailScreen->GetInbox() );
    218 				buttonWidget->RegisterEventObserver( userEmailScreen );
    219 			}
    220 		}
    221 		buttonWidget->RegisterEventObserver( &pdaScrollBar );
    222 		pdaList.AddChild( buttonWidget );
    223 	}
    224 	pdaList.AddChild( &pdaScrollBar );
    225 	pdaList.Initialize( this );
    226 
    227 	navBar.SetSpritePath( "navBar", "options" );
    228 	navBar.Initialize( this );
    229 	navBar.SetNumVisibleOptions( MAX_NAV_OPTIONS );
    230 	navBar.SetWrappingAllowed( true );
    231 	navBar.SetButtonSpacing( 20.0f, 25.0f, 75.0f );
    232 	navBar.SetInitialXPos( 40.0f );
    233 	navBar.SetNoAutoFree( true );
    234 	for ( int count = 0; count < ( MAX_NAV_OPTIONS * 2 - 1 ); ++count ) {
    235 		idMenuWidget_NavButton * const navButton = new (TAG_SWF) idMenuWidget_NavButton();
    236 
    237 		if ( count < MAX_NAV_OPTIONS - 1 ) {
    238 			navButton->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PDA_SELECT_NAV, count );
    239 		} else if ( count < ( ( MAX_NAV_OPTIONS - 1 ) * 2 ) ) {
    240 			int index = ( count - ( MAX_NAV_OPTIONS - 1 ) ) + 1;
    241 			navButton->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PDA_SELECT_NAV, index );
    242 		} else {
    243 			navButton->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_PDA_SELECT_NAV, -1 );
    244 		}
    245 
    246 		navBar.AddChild( navButton );
    247 	}
    248 
    249 	//
    250 	// command bar
    251 	//
    252 	commandBarWidget.SetAlignment( idMenuWidget_CommandBar::LEFT );
    253 	commandBarWidget.SetSpritePath( "prompts" );
    254 	commandBarWidget.Initialize( this );
    255 	commandBarWidget.SetNoAutoFree( true );
    256 
    257 	AddChild( &navBar );
    258 	AddChild( &pdaList );
    259 	AddChild( &pdaScrollBar );
    260 	AddChild( &commandBarWidget );
    261 
    262 	pdaList.AddEventAction( WIDGET_EVENT_SCROLL_DOWN_LSTICK ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_DOWN_LSTICK ) );
    263 	pdaList.AddEventAction( WIDGET_EVENT_SCROLL_UP_LSTICK ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER, WIDGET_EVENT_SCROLL_UP_LSTICK ) );
    264 	pdaList.AddEventAction( WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE ) );
    265 	pdaList.AddEventAction( WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE ) );	
    266 	pdaList.AddEventAction( WIDGET_EVENT_SCROLL_DOWN ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER, WIDGET_EVENT_SCROLL_DOWN ) );
    267 	pdaList.AddEventAction( WIDGET_EVENT_SCROLL_UP ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER, WIDGET_EVENT_SCROLL_UP ) );
    268 	pdaList.AddEventAction( WIDGET_EVENT_SCROLL_DOWN_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_DOWN_RELEASE ) );
    269 	pdaList.AddEventAction( WIDGET_EVENT_SCROLL_UP_RELEASE ).Set( new (TAG_SWF) idWidgetActionHandler( &pdaList, WIDGET_ACTION_EVENT_STOP_REPEATER, WIDGET_EVENT_SCROLL_UP_RELEASE ) );	
    270 
    271 	menuScreens[ PDA_AREA_USER_DATA ]->RegisterEventObserver( &pdaList );
    272 	menuScreens[ PDA_AREA_USER_EMAIL ]->RegisterEventObserver( &pdaList );
    273 
    274 	idPlayer * player = gameLocal.GetLocalPlayer();
    275 	if ( player != NULL ) {
    276 
    277 		for ( int j = 0; j < MAX_WEAPONS; j++ ) {
    278 			const char * weaponDefName = va( "def_weapon%d", j );
    279 			const char *weap = player->spawnArgs.GetString( weaponDefName );
    280 			if ( weap != NULL && *weap != NULL ) {
    281 				const idDeclEntityDef * weaponDef = gameLocal.FindEntityDef( weap, false );
    282 				if ( weaponDef != NULL ) {
    283 					declManager->FindMaterial( weaponDef->dict.GetString( "pdaIcon" ) );
    284 					declManager->FindMaterial( weaponDef->dict.GetString( "hudIcon" ) );
    285 				}
    286 			}
    287 		}
    288 
    289 	}
    290 
    291 	class idPDAGGUIClose : public idSWFScriptFunction_RefCounted {
    292 	public:
    293 		idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) {
    294 			idPlayer * player = gameLocal.GetLocalPlayer();
    295 			if ( player != NULL ) {
    296 				player->TogglePDA();
    297 			}
    298 			return idSWFScriptVar();
    299 		}
    300 	};	
    301 
    302 	if ( gui != NULL ) {
    303 		gui->SetGlobal( "closePDA", new idPDAGGUIClose() );
    304 	}
    305 
    306 	// precache sounds
    307 	// don't load gui music for the pause menu to save some memory
    308 	const idSoundShader * soundShader = NULL;
    309 	soundShader = declManager->FindSound( "gui/list_scroll", true );
    310 	if ( soundShader != NULL ) {
    311 		sounds[ GUI_SOUND_SCROLL ] = soundShader->GetName();
    312 	}
    313 	soundShader = declManager->FindSound( "gui/btn_PDA_advance", true );
    314 	if ( soundShader != NULL ) {
    315 		sounds[ GUI_SOUND_ADVANCE ] = soundShader->GetName();
    316 	}
    317 	soundShader = declManager->FindSound( "gui/btn_PDA_back", true );
    318 	if ( soundShader != NULL ) {
    319 		sounds[ GUI_SOUND_BACK ] = soundShader->GetName();
    320 	}
    321 	soundShader = declManager->FindSound( "gui/pda_next_tab", true );
    322 	if ( soundShader != NULL ) {
    323 		sounds[ GUI_SOUND_BUILD_ON ] = soundShader->GetName();
    324 	}
    325 	soundShader = declManager->FindSound( "gui/pda_prev_tab", true );
    326 	if ( soundShader != NULL ) {
    327 		sounds[ GUI_SOUND_BUILD_OFF ] = soundShader->GetName();
    328 	}
    329 	soundShader = declManager->FindSound( "gui/btn_set_focus", true );
    330 	if ( soundShader != NULL ) {
    331 		sounds[ GUI_SOUND_FOCUS ] = soundShader->GetName();
    332 	}
    333 	soundShader = declManager->FindSound( "gui/btn_roll_over", true );
    334 	if ( soundShader != NULL ) {
    335 		sounds[ GUI_SOUND_ROLL_OVER ] = soundShader->GetName();
    336 	}
    337 	soundShader = declManager->FindSound( "gui/btn_roll_out", true );
    338 	if ( soundShader != NULL ) {
    339 		sounds[ GUI_SOUND_ROLL_OUT ] = soundShader->GetName();
    340 	}
    341 }
    342 
    343 /*
    344 ========================
    345 idMenuHandler_PDA::HandleAction
    346 ========================
    347 */
    348 bool idMenuHandler_PDA::HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled ) {
    349 
    350 	if ( activeScreen == PDA_AREA_INVALID ) {
    351 		return true;
    352 	}
    353 	
    354 	widgetAction_t actionType = action.GetType();
    355 	const idSWFParmList & parms = action.GetParms();
    356 	
    357 	if ( event.type == WIDGET_EVENT_COMMAND ) {
    358 		if ( menuScreens[ activeScreen ] != NULL && !forceHandled ) {
    359 			if ( menuScreens[ activeScreen ]->HandleAction( action, event, widget, true ) ) {
    360 				if ( actionType == WIDGET_ACTION_GO_BACK ) {
    361 					PlaySound( GUI_SOUND_BACK );
    362 				} else {
    363 					PlaySound( GUI_SOUND_ADVANCE );
    364 				}
    365 				return true;
    366 			}
    367 		}
    368 	}
    369 
    370 	switch ( actionType ) {
    371 		case WIDGET_ACTION_PDA_SELECT_USER: {
    372 			int index = parms[0].ToInteger();
    373 			idMenuWidget_DynamicList * pdaList = dynamic_cast< idMenuWidget_DynamicList * >( GetChildFromIndex( PDA_WIDGET_PDA_LIST ) );
    374 			if ( pdaList != NULL ) {
    375 				pdaList->SetViewIndex( pdaList->GetViewOffset() + index );
    376 				pdaList->SetFocusIndex( index );
    377 			}
    378 			return true;
    379 		}
    380 		case WIDGET_ACTION_SCROLL_TAB: {
    381 
    382 			if ( transition != MENU_TRANSITION_INVALID ) {
    383 				return true;
    384 			}
    385 			int delta = parms[0].ToInteger();
    386 			idMenuWidget_NavBar * navBar = dynamic_cast< idMenuWidget_NavBar * >( GetChildFromIndex( PDA_WIDGET_NAV_BAR ) );
    387 			if ( navBar != NULL ) {
    388 				int focused = navBar->GetFocusIndex();
    389 				focused += delta;
    390 				if ( focused < 0 ) {
    391 					focused = navBar->GetNumVisibleOptions() - 1;
    392 				} else if ( focused >= navBar->GetNumVisibleOptions() ) {
    393 					focused = 0;
    394 				}
    395 
    396 				navBar->SetViewIndex( focused );
    397 				navBar->SetFocusIndex( focused, true );
    398 				navBar->Update();
    399 
    400 				nextScreen = activeScreen + delta;
    401 				if ( nextScreen < 0 ) {
    402 					nextScreen = PDA_NUM_AREAS - 1;
    403 				} else if ( nextScreen == PDA_NUM_AREAS ) {
    404 					nextScreen = 0;
    405 				}
    406 
    407 				if ( delta < 0 ) {					
    408 					transition = MENU_TRANSITION_BACK;
    409 				} else {
    410 					transition = MENU_TRANSITION_ADVANCE;
    411 				}
    412 
    413 			}
    414 			return true;
    415 		}
    416 		case WIDGET_ACTION_PDA_SELECT_NAV: {
    417 			int index = parms[0].ToInteger();
    418 			
    419 			if ( index == -1 && activeScreen == PDA_AREA_USER_EMAIL ) {
    420 				idMenuScreen_PDA_UserEmails * screen = dynamic_cast< idMenuScreen_PDA_UserEmails * const >( menuScreens[ PDA_AREA_USER_EMAIL ] );
    421 				if ( screen ) {
    422 					screen->ShowEmail( false );
    423 				}
    424 				return true;
    425 			}
    426 
    427 			// click on the current nav tab
    428 			if ( index == -1 ) {
    429 				return true;
    430 			}
    431 
    432 			idMenuWidget_NavBar * navBar = dynamic_cast< idMenuWidget_NavBar * >( GetChildFromIndex( PDA_WIDGET_NAV_BAR ) );
    433 			if ( navBar != NULL ) {
    434 				navBar->SetViewIndex( navBar->GetViewOffset() + index );
    435 				navBar->SetFocusIndex( index, true );
    436 				navBar->Update();
    437 
    438 				if ( index < activeScreen ) {
    439 					nextScreen = index;
    440 					transition = MENU_TRANSITION_BACK;
    441 				} else if ( index > activeScreen ) {
    442 					nextScreen = index;
    443 					transition = MENU_TRANSITION_ADVANCE;
    444 				}
    445 			}			
    446 			return true;
    447 		}
    448 		case WIDGET_ACTION_SELECT_PDA_AUDIO: {
    449 			if ( activeScreen == PDA_AREA_USER_DATA ) {
    450 				int index = parms[0].ToInteger();
    451 				idMenuWidget_DynamicList * pdaList = dynamic_cast< idMenuWidget_DynamicList * >( GetChildFromIndex( PDA_WIDGET_PDA_LIST ) );
    452 				
    453 				bool change = false;
    454 				if ( pdaList != NULL ) {
    455 					int pdaIndex = pdaList->GetViewIndex();
    456 					change = PlayPDAAudioLog( pdaIndex, index );
    457 				}
    458 
    459 				if ( change ) {
    460 					if ( widget->GetParent() != NULL ) {
    461 						idMenuWidget_DynamicList * audioList = dynamic_cast< idMenuWidget_DynamicList * >( widget->GetParent() );
    462 						int index = parms[0].ToInteger();
    463 						if ( audioList != NULL ) {
    464 							audioList->SetFocusIndex( index );
    465 						}
    466 					}
    467 				}
    468 			}
    469 
    470 			return true;
    471 		}
    472 		case WIDGET_ACTION_SELECT_PDA_VIDEO: {
    473 			if ( activeScreen == PDA_AREA_VIDEO_DISKS ) {
    474 				int index = parms[0].ToInteger();
    475 				if ( menuScreens[ PDA_AREA_VIDEO_DISKS ] != NULL ) {
    476 					idMenuScreen_PDA_VideoDisks * screen = dynamic_cast< idMenuScreen_PDA_VideoDisks * const >( menuScreens[ PDA_AREA_VIDEO_DISKS ] );
    477 					if ( screen != NULL ) {
    478 						screen->SelectedVideoToPlay( index );
    479 					}
    480 				}
    481 			}
    482 			return true;
    483 		}
    484 	}
    485 
    486 	return idMenuHandler::HandleAction( action, event, widget, forceHandled );
    487 }
    488 
    489 /*
    490 ========================
    491 idMenuHandler_PDA::PlayPDAAudioLog
    492 ========================
    493 */
    494 bool idMenuHandler_PDA::PlayPDAAudioLog( int pdaIndex, int audioIndex ) {
    495 	idPlayer * player = gameLocal.GetLocalPlayer();
    496 	if ( player != NULL ) {
    497 		const idDeclPDA * pda = player->GetInventory().pdas[ pdaIndex ];
    498 		if ( pda != NULL && pda->GetNumAudios() > audioIndex ) {
    499 			const idDeclAudio *aud = pda->GetAudioByIndex( audioIndex );
    500 
    501 			if ( audioFile == aud ) {
    502 				player->EndAudioLog();
    503 				return true;
    504 			} else if ( aud != NULL ) {
    505 				audioFile = aud;
    506 				player->EndAudioLog();
    507 				player->PlayAudioLog( aud->GetWave() );
    508 				return true;
    509 			}
    510 		}
    511 	}
    512 	return false;
    513 }
    514 
    515 /*
    516 ========================
    517 idMenuHandler_PDA::GetMenuScreen
    518 ========================
    519 */
    520 idMenuScreen * idMenuHandler_PDA::GetMenuScreen( int index ) {
    521 
    522 	if ( index < 0 || index >= PDA_NUM_AREAS ) {
    523 		return NULL;
    524 	}
    525 
    526 	return menuScreens[ index ];
    527 
    528 }
    529 
    530 /*
    531 ========================
    532 idMenuHandler_PDA::GetMenuScreen
    533 ========================
    534 */
    535 void idMenuHandler_PDA::UpdateAudioLogPlaying( bool playing ) {
    536 
    537 	if ( playing != audioLogPlaying && activeScreen == PDA_AREA_USER_DATA && menuScreens[ activeScreen ] != NULL ) {
    538 		menuScreens[ activeScreen ]->Update();
    539 	}
    540 
    541 	audioLogPlaying = playing;
    542 	if ( !playing ) {
    543 		audioFile = NULL;
    544 	}
    545 }
    546 
    547 /*
    548 ========================
    549 idMenuHandler_PDA::GetMenuScreen
    550 ========================
    551 */
    552 void idMenuHandler_PDA::UdpateVideoPlaying( bool playing ) {
    553 
    554 	if ( playing != videoPlaying ) {
    555 		if ( activeScreen == PDA_AREA_VIDEO_DISKS && menuScreens[ activeScreen ] != NULL ) {		
    556 			idPlayer * player = gameLocal.GetLocalPlayer();
    557 			if ( !playing ) {
    558 				player->EndVideoDisk();
    559 			}
    560 
    561 			idMenuScreen_PDA_VideoDisks * screen = dynamic_cast< idMenuScreen_PDA_VideoDisks * const >( menuScreens[ PDA_AREA_VIDEO_DISKS ] );
    562 			if ( screen != NULL ) {
    563 				if ( !playing ) {
    564 					screen->ClearActiveVideo();
    565 				}
    566 				screen->Update();
    567 			}
    568 		}
    569 
    570 		videoPlaying = playing;		
    571 	}	
    572 }
    573 
    574  /*
    575  ================================================
    576  idMenuHandler_PDA::Cleanup
    577  ================================================
    578  */
    579  void idMenuHandler_PDA::Cleanup() {
    580 	 idMenuHandler::Cleanup();
    581 	 for ( int index = 0; index < MAX_SCREEN_AREAS; ++index ) {
    582 		 delete menuScreens[ index ];
    583 		 menuScreens[ index ] = NULL;
    584 	 }
    585  }
    586 
    587 
    588   /*
    589  ================================================
    590  idMenuHandler_PDA::~idMenuHandler_PDA
    591  ================================================
    592  */
    593  idMenuHandler_PDA::~idMenuHandler_PDA() {
    594 	 pdaScrollBar.Cleanup();
    595 	 pdaList.Cleanup();
    596 	 navBar.Cleanup();
    597 	 commandBarWidget.Cleanup();
    598 	 Cleanup();
    599  }