MenuWidget_DevList.cpp (7393B)
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 "../precompiled.h" 30 #include "../MainMenuLocal.h" 31 32 /* 33 ================================================================================================ 34 idMenuWidget_DevList 35 36 Extends the standard list widget to support the developer menu. 37 ================================================================================================ 38 */ 39 40 namespace { 41 /* 42 ================================================ 43 DevList_NavigateForward 44 ================================================ 45 */ 46 class DevList_NavigateForward : public idSWFScriptFunction_RefCounted { 47 public: 48 DevList_NavigateForward( idMenuWidget_DevList * devList_, const int optionIndex_ ) : 49 devList( devList_ ), 50 optionIndex( optionIndex_ ) { 51 52 } 53 54 idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) { 55 devList->NavigateForward( optionIndex ); 56 return idSWFScriptVar(); 57 } 58 59 private: 60 idMenuWidget_DevList * devList; 61 int optionIndex; 62 }; 63 } 64 65 /* 66 ======================== 67 idMenuWidget_DevList::Initialize 68 ======================== 69 */ 70 void idMenuWidget_DevList::Initialize() { 71 AddEventAction( WIDGET_EVENT_SCROLL_DOWN ).Set( WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_VERTICAL, 1 ); 72 AddEventAction( WIDGET_EVENT_SCROLL_UP ).Set( WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_VERTICAL, -1 ); 73 AddEventAction( WIDGET_EVENT_SCROLL_DOWN_RELEASE ).Set( WIDGET_ACTION_STOP_REPEATER ); 74 AddEventAction( WIDGET_EVENT_SCROLL_UP_RELEASE ).Set( WIDGET_ACTION_STOP_REPEATER ); 75 76 int optionIndex = 0; 77 while ( GetChildren().Num() < GetNumVisibleOptions() ) { 78 idMenuWidget_Button * const buttonWidget = new ( TAG_MENU ) idMenuWidget_Button(); 79 buttonWidget->AddEventAction( WIDGET_EVENT_PRESS ).Set( new ( TAG_SWF ) DevList_NavigateForward( this, optionIndex++ ) ); 80 AddChild( buttonWidget ); 81 } 82 } 83 84 /* 85 ======================== 86 idMenuWidget_DevList::GetTotalNumberOfOptions 87 ======================== 88 */ 89 int idMenuWidget_DevList::GetTotalNumberOfOptions() const { 90 if ( devMenuList == NULL ) { 91 return 0; 92 } 93 94 return devMenuList->devMenuList.Num(); 95 } 96 97 /* 98 ======================== 99 idMenuWidget_DevList::GoToFirstMenu 100 ======================== 101 */ 102 void idMenuWidget_DevList::GoToFirstMenu() { 103 devMapListInfos.Clear(); 104 indexInfo_t & info = devMapListInfos.Alloc(); 105 info.name = "devmenuoption/main"; 106 107 devMenuList = NULL; 108 109 RecalculateDevMenu(); 110 } 111 112 /* 113 ======================== 114 idMenuWidget_DevList::NavigateForward 115 ======================== 116 */ 117 void idMenuWidget_DevList::NavigateForward( const int optionIndex ) { 118 if ( devMenuList == NULL ) { 119 return; 120 } 121 122 const int focusedIndex = GetViewOffset() + optionIndex; 123 124 const idDeclDevMenuList::idDevMenuOption & devOption = devMenuList->devMenuList[ focusedIndex ]; 125 if ( ( devOption.devMenuDisplayName.Length() == 0 ) || ( devOption.devMenuDisplayName.Cmp( "..." ) == 0 ) ) { 126 return; 127 } 128 129 if ( devOption.devMenuSubList != NULL ) { 130 indexInfo_t & indexes = devMapListInfos.Alloc(); 131 indexes.name = devOption.devMenuSubList->GetName(); 132 indexes.focusIndex = GetFocusIndex(); 133 indexes.viewIndex = GetViewIndex(); 134 indexes.viewOffset = GetViewOffset(); 135 136 RecalculateDevMenu(); 137 138 SetViewIndex( 0 ); 139 SetViewOffset( 0 ); 140 141 Update(); 142 143 // NOTE: This must be done after the Update() because it MAY change the sprites that 144 // children refer to 145 GetChildByIndex( 0 ).SetState( WIDGET_STATE_SELECTED ); 146 ForceFocusIndex( 0 ); 147 SetFocusIndex( 0 ); 148 149 gameLocal->GetMainMenu()->ClearWidgetActionRepeater(); 150 } else { 151 cmdSystem->AppendCommandText( va( "loadDevMenuOption %s %d\n", devMapListInfos[ devMapListInfos.Num() - 1 ].name, focusedIndex ) ); 152 } 153 } 154 155 /* 156 ======================== 157 idMenuWidget_DevList::NavigateBack 158 ======================== 159 */ 160 void idMenuWidget_DevList::NavigateBack() { 161 assert( devMapListInfos.Num() != 0 ); 162 if ( devMapListInfos.Num() == 1 ) { 163 // Important that this goes through as a DIRECT event, since more than likely the list 164 // widget will have the parent's focus, so a standard ReceiveEvent() here would turn 165 // into an infinite recursion. 166 idWidgetEvent event( WIDGET_EVENT_BACK, 0, NULL, idSWFParmList() ); 167 168 idWidgetAction action; 169 action.Set( WIDGET_ACTION_GO_BACK, MENU_ROOT ); 170 HandleAction( action, event ); 171 172 return; 173 } 174 175 // NOTE: we need a copy here, since it's about to be removed from the list 176 const indexInfo_t indexes = devMapListInfos[ devMapListInfos.Num() - 1 ]; 177 assert( indexes.focusIndex < GetChildren().Num() ); 178 assert( ( indexes.viewIndex - indexes.viewOffset ) < GetNumVisibleOptions() ); 179 devMapListInfos.RemoveIndex( devMapListInfos.Num() - 1 ); 180 181 RecalculateDevMenu(); 182 183 SetViewIndex( indexes.viewIndex ); 184 SetViewOffset( indexes.viewOffset ); 185 186 Update(); 187 188 // NOTE: This must be done AFTER Update() because so that it is sure to refer to the proper sprite 189 GetChildByIndex( indexes.focusIndex ).SetState( WIDGET_STATE_SELECTED ); 190 ForceFocusIndex( indexes.focusIndex ); 191 SetFocusIndex( indexes.focusIndex ); 192 193 gameLocal->GetMainMenu()->ClearWidgetActionRepeater(); 194 } 195 196 197 /* 198 ======================== 199 idMenuWidget_DevList::RecalculateDevMenu 200 ======================== 201 */ 202 void idMenuWidget_DevList::RecalculateDevMenu() { 203 if ( devMapListInfos.Num() > 0 ) { 204 const idDeclDevMenuList * const devMenuListDecl = idDeclDevMenuList::resourceList.Load( devMapListInfos[ devMapListInfos.Num() - 1 ].name, false ); 205 if ( devMenuListDecl != NULL ) { 206 devMenuList = devMenuListDecl; 207 } 208 } 209 210 idSWFScriptObject & root = gameLocal->GetMainMenu()->GetSWF()->GetRootObject(); 211 for ( int i = 0; i < GetChildren().Num(); ++i ) { 212 idMenuWidget & child = GetChildByIndex( i ); 213 child.SetSpritePath( GetSpritePath(), va( "option%d", i ) ); 214 if ( child.BindSprite( root ) ) { 215 child.SetState( WIDGET_STATE_NORMAL ); 216 child.GetSprite()->StopFrame( 1 ); 217 } 218 } 219 }