MenuWidget.h (40639B)
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 #ifndef __MENU_WIDGET_H__ 29 #define __MENU_WIDGET_H__ 30 31 class idMenuHandler; 32 class idMenuWidget; 33 34 enum menuOption_t { 35 OPTION_INVALID = -1, 36 OPTION_BUTTON_TEXT, 37 OPTION_SLIDER_BAR, 38 OPTION_SLIDER_TEXT, 39 OPTION_SLIDER_TOGGLE, 40 OPTION_BUTTON_INFO, 41 OPTION_BUTTON_FULL_TEXT_SLIDER, 42 MAX_MENU_OPTION_TYPES 43 }; 44 45 enum widgetEvent_t { 46 WIDGET_EVENT_PRESS, 47 WIDGET_EVENT_RELEASE, 48 WIDGET_EVENT_ROLL_OVER, 49 WIDGET_EVENT_ROLL_OUT, 50 WIDGET_EVENT_FOCUS_ON, 51 WIDGET_EVENT_FOCUS_OFF, 52 53 WIDGET_EVENT_SCROLL_UP_LSTICK, 54 WIDGET_EVENT_SCROLL_UP_LSTICK_RELEASE, 55 WIDGET_EVENT_SCROLL_DOWN_LSTICK, 56 WIDGET_EVENT_SCROLL_DOWN_LSTICK_RELEASE, 57 WIDGET_EVENT_SCROLL_LEFT_LSTICK, 58 WIDGET_EVENT_SCROLL_LEFT_LSTICK_RELEASE, 59 WIDGET_EVENT_SCROLL_RIGHT_LSTICK, 60 WIDGET_EVENT_SCROLL_RIGHT_LSTICK_RELEASE, 61 62 WIDGET_EVENT_SCROLL_UP_RSTICK, 63 WIDGET_EVENT_SCROLL_UP_RSTICK_RELEASE, 64 WIDGET_EVENT_SCROLL_DOWN_RSTICK, 65 WIDGET_EVENT_SCROLL_DOWN_RSTICK_RELEASE, 66 WIDGET_EVENT_SCROLL_LEFT_RSTICK, 67 WIDGET_EVENT_SCROLL_LEFT_RSTICK_RELEASE, 68 WIDGET_EVENT_SCROLL_RIGHT_RSTICK, 69 WIDGET_EVENT_SCROLL_RIGHT_RSTICK_RELEASE, 70 71 WIDGET_EVENT_SCROLL_UP, 72 WIDGET_EVENT_SCROLL_UP_RELEASE, 73 WIDGET_EVENT_SCROLL_DOWN, 74 WIDGET_EVENT_SCROLL_DOWN_RELEASE, 75 WIDGET_EVENT_SCROLL_LEFT, 76 WIDGET_EVENT_SCROLL_LEFT_RELEASE, 77 WIDGET_EVENT_SCROLL_RIGHT, 78 WIDGET_EVENT_SCROLL_RIGHT_RELEASE, 79 80 WIDGET_EVENT_DRAG_START, 81 WIDGET_EVENT_DRAG_STOP, 82 83 WIDGET_EVENT_SCROLL_PAGEDWN, 84 WIDGET_EVENT_SCROLL_PAGEDWN_RELEASE, 85 WIDGET_EVENT_SCROLL_PAGEUP, 86 WIDGET_EVENT_SCROLL_PAGEUP_RELEASE, 87 88 WIDGET_EVENT_SCROLL, 89 WIDGET_EVENT_SCROLL_RELEASE, 90 WIDGET_EVENT_BACK, 91 WIDGET_EVENT_COMMAND, 92 WIDGET_EVENT_TAB_NEXT, 93 WIDGET_EVENT_TAB_PREV, 94 MAX_WIDGET_EVENT 95 }; 96 97 enum scrollType_t { 98 SCROLL_SINGLE, // scroll a single unit 99 SCROLL_PAGE, // scroll a page 100 SCROLL_FULL, // scroll all the way to the end 101 SCROLL_TOP, // scroll to the first selection 102 SCROLL_END, // scroll to the last selection 103 }; 104 105 enum widgetAction_t { 106 WIDGET_ACTION_NONE, 107 WIDGET_ACTION_COMMAND, 108 WIDGET_ACTION_FUNCTION, // call the SWF function 109 WIDGET_ACTION_SCROLL_VERTICAL, // scroll something. takes one param = amount to scroll (can be negative) 110 WIDGET_ACTION_SCROLL_VERTICAL_VARIABLE, 111 WIDGET_ACTION_SCROLL_PAGE, 112 WIDGET_ACTION_SCROLL_HORIZONTAL, // scroll something. takes one param = amount to scroll (can be negative) 113 WIDGET_ACTION_SCROLL_TAB, 114 WIDGET_ACTION_START_REPEATER, 115 WIDGET_ACTION_STOP_REPEATER, 116 WIDGET_ACTION_ADJUST_FIELD, 117 WIDGET_ACTION_PRESS_FOCUSED, 118 WIDGET_ACTION_JOY3_ON_PRESS, 119 WIDGET_ACTION_JOY4_ON_PRESS, 120 // 121 WIDGET_ACTION_GOTO_MENU, 122 WIDGET_ACTION_GO_BACK, 123 WIDGET_ACTION_EXIT_GAME, 124 WIDGET_ACTION_LAUNCH_MULTIPLAYER, 125 WIDGET_ACTION_MENU_BAR_SELECT, 126 WIDGET_ACTION_EMAIL_HOVER, 127 // PDA USER DATA ACTIONS 128 WIDGET_ACTION_PDA_SELECT_USER, 129 WIDGET_ACTION_SELECT_GAMERTAG, 130 WIDGET_ACTION_PDA_SELECT_NAV, 131 WIDGET_ACTION_SELECT_PDA_AUDIO, 132 WIDGET_ACTION_SELECT_PDA_VIDEO, 133 WIDGET_ACTION_SELECT_PDA_ITEM, 134 WIDGET_ACTION_SCROLL_DRAG, 135 // PDA EMAIL ACTIONS 136 WIDGET_ACTION_PDA_SELECT_EMAIL, 137 WIDGET_ACTION_PDA_CLOSE, 138 WIDGET_ACTION_REFRESH, 139 WIDGET_ACTION_MUTE_PLAYER, 140 MAX_WIDGET_ACTION 141 }; 142 143 enum actionHandler_t { 144 WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER, 145 WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER_VARIABLE, 146 WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER, 147 WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER_VARIABLE, 148 WIDGET_ACTION_EVENT_SCROLL_LEFT_START_REPEATER, 149 WIDGET_ACTION_EVENT_SCROLL_RIGHT_START_REPEATER, 150 WIDGET_ACTION_EVENT_SCROLL_PAGE_DOWN_START_REPEATER, 151 WIDGET_ACTION_EVENT_SCROLL_PAGE_UP_START_REPEATER, 152 WIDGET_ACTION_EVENT_STOP_REPEATER, 153 WIDGET_ACTION_EVENT_TAB_NEXT, 154 WIDGET_ACTION_EVENT_TAB_PREV, 155 WIDGET_ACTION_EVENT_DRAG_START, 156 WIDGET_ACTION_EVENT_DRAG_STOP, 157 WIDGET_ACTION_EVENT_JOY3_ON_PRESS, 158 }; 159 160 struct widgetTransition_t { 161 widgetTransition_t() : 162 animationName( NULL ) { 163 164 } 165 166 const char * animationName; // name of the animation to run 167 idStaticList< const char *, 4 > prefixes; // prefixes to try to use for animation 168 }; 169 170 171 /* 172 ================================================ 173 scoreboardInfo_t 174 ================================================ 175 */ 176 struct scoreboardInfo_t { 177 scoreboardInfo_t() : 178 index( -1 ), 179 voiceState( VOICECHAT_DISPLAY_NONE ) { 180 } 181 182 idList< idStr, TAG_IDLIB_LIST_MENU> values; 183 int index; 184 voiceStateDisplay_t voiceState; 185 }; 186 187 /* 188 ================================================ 189 idSort_SavesByDate 190 ================================================ 191 */ 192 class idSort_SavesByDate : public idSort_Quick< idSaveGameDetails, idSort_SavesByDate > { 193 public: 194 int Compare( const idSaveGameDetails & a, const idSaveGameDetails & b ) const { 195 return b.date - a.date; 196 } 197 }; 198 199 /* 200 ================================================ 201 idMenuDataSource 202 ================================================ 203 */ 204 class idMenuDataSource { 205 public: 206 virtual ~idMenuDataSource() { } 207 208 virtual void LoadData() = 0; 209 virtual void CommitData() = 0; 210 virtual bool IsDataChanged() const = 0; 211 virtual idSWFScriptVar GetField( const int fieldIndex ) const = 0; 212 virtual void AdjustField( const int fieldIndex, const int adjustAmount ) = 0; 213 }; 214 215 /* 216 ================================================ 217 idWidgetEvent 218 ================================================ 219 */ 220 class idWidgetEvent { 221 public: 222 idWidgetEvent() : 223 type( WIDGET_EVENT_PRESS ), 224 arg( 0 ), 225 thisObject( NULL ) { 226 227 } 228 229 idWidgetEvent( const widgetEvent_t type_, const int arg_, idSWFScriptObject * thisObject_, const idSWFParmList & parms_ ) : 230 type( type_ ), 231 arg( arg_ ), 232 thisObject( thisObject_ ), 233 parms( parms_ ) { 234 } 235 236 widgetEvent_t type; 237 int arg; 238 idSWFScriptObject * thisObject; 239 idSWFParmList parms; 240 }; 241 242 /* 243 ================================================ 244 idWidgetAction 245 ================================================ 246 */ 247 class idWidgetAction { 248 public: 249 idWidgetAction() : 250 action( WIDGET_ACTION_NONE ), 251 scriptFunction( NULL ) { 252 } 253 254 idWidgetAction( const idWidgetAction & src ) { 255 action = src.action; 256 parms = src.parms; 257 scriptFunction = src.scriptFunction; 258 if ( scriptFunction != NULL ) { 259 scriptFunction->AddRef(); 260 } 261 } 262 263 ~idWidgetAction() { 264 if ( scriptFunction != NULL ) { 265 scriptFunction->Release(); 266 } 267 } 268 269 void operator=( const idWidgetAction & src ) { 270 action = src.action; 271 parms = src.parms; 272 scriptFunction = src.scriptFunction; 273 if ( scriptFunction != NULL ) { 274 scriptFunction->AddRef(); 275 } 276 } 277 278 bool operator==( const idWidgetAction & otherAction ) const { 279 if ( GetType() != otherAction.GetType() 280 || GetParms().Num() != otherAction.GetParms().Num() ) { 281 return false; 282 } 283 284 // everything else is equal, so check all parms. NOTE: this assumes we are only sending 285 // integral types. 286 for ( int i = 0; i < GetParms().Num(); ++i ) { 287 if ( GetParms()[ i ].GetType() != otherAction.GetParms()[ i ].GetType() 288 || GetParms()[ i ].ToInteger() != otherAction.GetParms()[ i ].ToInteger() ) { 289 return false; 290 } 291 } 292 293 return true; 294 } 295 296 void Set( idSWFScriptFunction * function ) { 297 action = WIDGET_ACTION_FUNCTION; 298 if ( scriptFunction != NULL ) { 299 scriptFunction->Release(); 300 } 301 scriptFunction = function; 302 scriptFunction->AddRef(); 303 } 304 305 void Set( widgetAction_t action_ ) { 306 action = action_; 307 parms.Clear(); 308 } 309 310 void Set( widgetAction_t action_, const idSWFScriptVar & var1 ) { 311 action = action_; 312 parms.Clear(); 313 parms.Append( var1 ); 314 } 315 316 void Set( widgetAction_t action_, const idSWFScriptVar & var1, const idSWFScriptVar & var2 ) { 317 action = action_; 318 parms.Clear(); 319 parms.Append( var1 ); 320 parms.Append( var2 ); 321 } 322 323 void Set( widgetAction_t action_, const idSWFScriptVar & var1, const idSWFScriptVar & var2, const idSWFScriptVar & var3 ) { 324 action = action_; 325 parms.Clear(); 326 parms.Append( var1 ); 327 parms.Append( var2 ); 328 parms.Append( var3 ); 329 } 330 331 void Set( widgetAction_t action_, const idSWFScriptVar & var1, const idSWFScriptVar & var2, const idSWFScriptVar & var3, const idSWFScriptVar & var4 ) { 332 action = action_; 333 parms.Clear(); 334 parms.Append( var1 ); 335 parms.Append( var2 ); 336 parms.Append( var3 ); 337 parms.Append( var4 ); 338 } 339 340 idSWFScriptFunction * GetScriptFunction() { return scriptFunction; } 341 const widgetAction_t GetType() const { return action; } 342 const idSWFParmList & GetParms() const { return parms; } 343 344 private: 345 widgetAction_t action; 346 idSWFParmList parms; 347 idSWFScriptFunction * scriptFunction; 348 }; 349 350 typedef idList< idMenuWidget *, TAG_IDLIB_LIST_MENU > idMenuWidgetList; 351 352 /* 353 ================================================ 354 idMenuWidget 355 356 We're using a model/view architecture, so this is the combination of both model and view. The 357 other part of the view is the SWF itself. 358 ================================================ 359 */ 360 class idMenuWidget { 361 public: 362 363 /* 364 ================================================ 365 WrapWidgetSWFEvent 366 ================================================ 367 */ 368 class WrapWidgetSWFEvent : public idSWFScriptFunction_RefCounted { 369 public: 370 WrapWidgetSWFEvent( idMenuWidget * widget, const widgetEvent_t event, const int eventArg ) : 371 targetWidget( widget ), 372 targetEvent( event ), 373 targetEventArg( eventArg ) { 374 } 375 376 idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) { 377 targetWidget->ReceiveEvent( idWidgetEvent( targetEvent, targetEventArg, thisObject, parms ) ); 378 return idSWFScriptVar(); 379 } 380 381 private: 382 idMenuWidget * targetWidget; 383 widgetEvent_t targetEvent; 384 int targetEventArg; 385 }; 386 387 388 enum widgetState_t { 389 WIDGET_STATE_HIDDEN, // hidden 390 WIDGET_STATE_NORMAL, // normal 391 WIDGET_STATE_SELECTING, // going into the selected state 392 WIDGET_STATE_SELECTED, // fully selected 393 WIDGET_STATE_DISABLED, // disabled 394 WIDGET_STATE_MAX 395 }; 396 397 idMenuWidget(); 398 399 virtual ~idMenuWidget(); 400 401 void Cleanup(); 402 // typically this is where the allocations for a widget will occur: sub widgets, etc. 403 // Note that SWF sprite objects may not be accessible at this point. 404 virtual void Initialize( idMenuHandler * data ) { menuData = data; } 405 406 // takes the information described in this widget and applies it to a given script object. 407 // the script object should point to the root that you want to run from. Running this will 408 // also create the sprite binding, if any. 409 virtual void Update() {} 410 virtual void Show(); 411 virtual void Hide(); 412 413 widgetState_t GetState() const { return widgetState; } 414 void SetState( const widgetState_t state ); 415 416 // actually binds the sprite. this must be called after setting sprite path! 417 idSWFSpriteInstance * GetSprite() { return boundSprite; } 418 idSWF * GetSWFObject(); 419 idMenuHandler * GetMenuData(); 420 bool BindSprite( idSWFScriptObject & root ); 421 void ClearSprite(); 422 423 void SetSpritePath( const char * arg1, const char * arg2 = NULL, const char * arg3 = NULL, const char * arg4 = NULL, const char * arg5 = NULL ); 424 void SetSpritePath( const idList< idStr > & spritePath_, const char * arg1 = NULL, const char * arg2 = NULL, const char * arg3 = NULL, const char * arg4 = NULL, const char * arg5 = NULL ); 425 idList< idStr, TAG_IDLIB_LIST_MENU > & GetSpritePath() { return spritePath; } 426 int GetRefCount() const { return refCount; } 427 void AddRef() { refCount++; } 428 void Release() { assert( refCount > 0 ); if ( --refCount == 0 && !noAutoFree ) { delete this; } } 429 430 //------------------------ 431 // Event Handling 432 //------------------------ 433 virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false ); 434 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ) { } 435 void SendEventToObservers( const idWidgetEvent & event ); 436 void RegisterEventObserver( idMenuWidget * observer ); 437 void ReceiveEvent( const idWidgetEvent & event ); 438 439 // Executes an event in the context of this widget. Only rarely should this be called 440 // directly. Instead calls should go through ReceiveEvent which will propagate the event 441 // through the standard focus order. 442 virtual bool ExecuteEvent( const idWidgetEvent & event ); 443 444 // returns the list of actions for a given event, or NULL if no actions are registered for 445 // that event. Events should not be directly added to the returned list. Instead use 446 // AddEventAction for adding new events. 447 idList< idWidgetAction, TAG_IDLIB_LIST_MENU > * GetEventActions( const widgetEvent_t eventType ); 448 449 // allocates an action for the given event 450 idWidgetAction & AddEventAction( const widgetEvent_t eventType ); 451 void ClearEventActions(); 452 453 //------------------------ 454 // Data modeling 455 //------------------------ 456 void SetDataSource( idMenuDataSource * dataSource, const int fieldIndex ); 457 idMenuDataSource * GetDataSource() { return dataSource; } 458 void SetDataSourceFieldIndex( const int dataSourceFieldIndex_ ) { dataSourceFieldIndex = dataSourceFieldIndex_; } 459 int GetDataSourceFieldIndex() const { return dataSourceFieldIndex; } 460 461 idMenuWidget * GetFocus() { return ( focusIndex >= 0 && focusIndex < children.Num() ) ? children[ focusIndex ] : NULL; } 462 int GetFocusIndex() const { return focusIndex; } 463 void SetFocusIndex( const int index, bool skipSound = false ); 464 465 //------------------------ 466 // Hierarchy 467 //------------------------ 468 idMenuWidgetList & GetChildren() { return children; } 469 const idMenuWidgetList & GetChildren() const { return children; } 470 idMenuWidget & GetChildByIndex( const int index ) const { return *children[ index ]; } 471 472 void AddChild( idMenuWidget * widget ); 473 void RemoveChild( idMenuWidget * widget ); 474 bool HasChild( idMenuWidget * widget ); 475 void RemoveAllChildren(); 476 477 idMenuWidget * GetParent() { return parent; } 478 const idMenuWidget * GetParent() const { return parent; } 479 void SetParent( idMenuWidget * parent_ ) { parent = parent_; } 480 void SetSWFObj( idSWF * obj ) { swfObj = obj; } 481 bool GetHandlerIsParent() { return handlerIsParent; } 482 void SetHandlerIsParent( bool val ) { handlerIsParent = val; } 483 void SetNoAutoFree( bool b ) { noAutoFree = b; } 484 485 protected: 486 void ForceFocusIndex( const int index ) { focusIndex = index; } 487 488 protected: 489 bool handlerIsParent; 490 idMenuHandler * menuData; 491 idSWF * swfObj; 492 idSWFSpriteInstance * boundSprite; 493 idMenuWidget * parent; 494 idList< idStr, TAG_IDLIB_LIST_MENU > spritePath; 495 idMenuWidgetList children; 496 idMenuWidgetList observers; 497 498 static const int INVALID_ACTION_INDEX = -1; 499 idList< idList< idWidgetAction, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > eventActions; 500 idStaticList< int, MAX_WIDGET_EVENT > eventActionLookup; 501 502 idMenuDataSource * dataSource; 503 int dataSourceFieldIndex; 504 505 int focusIndex; 506 507 widgetState_t widgetState; 508 int refCount; 509 bool noAutoFree; 510 }; 511 512 /* 513 ================================================ 514 idMenuWidget_Button 515 516 This might be better named "ComboButton", as it contains behavior for several controls along 517 with standard button behavior. 518 ================================================ 519 */ 520 class idMenuWidget_Button : public idMenuWidget { 521 public: 522 523 enum animState_t { 524 ANIM_STATE_UP, // standard 525 ANIM_STATE_DOWN, // pressed down 526 ANIM_STATE_OVER, // hovered over this 527 ANIM_STATE_MAX 528 }; 529 530 idMenuWidget_Button() : 531 animState( ANIM_STATE_UP ), 532 img( NULL ), 533 ignoreColor( false ) { 534 } 535 536 virtual ~idMenuWidget_Button() {} 537 538 virtual bool ExecuteEvent( const idWidgetEvent & event ); 539 virtual void Update(); 540 541 //--------------- 542 // Model 543 //--------------- 544 void SetLabel( const idStr & label ) { btnLabel = label; } 545 const idStr & GetLabel() const { return btnLabel; } 546 void SetValues( idList< idStr > & list ); 547 const idStr & GetValue( int index ) const; 548 void SetImg( const idMaterial * val ) { img = val; } 549 const idMaterial * GetImg() { return img; } 550 void SetDescription( const char * desc_ ) { description = desc_; } 551 const idStr & GetDescription() const { return description; } 552 553 void SetIgnoreColor( const bool b ) { ignoreColor = b; } 554 555 animState_t GetAnimState() const { return animState; } 556 void SetAnimState( const animState_t state ) { animState = state; } 557 void SetOnPressFunction( idSWFScriptFunction * func ) { scriptFunction = func; } 558 559 protected: 560 void SetupTransitionInfo( widgetTransition_t & trans, const widgetState_t buttonState, const animState_t sourceAnimState, const animState_t destAnimState ) const; 561 void AnimateToState( const animState_t targetState, const bool force = false ); 562 563 idList< idStr, TAG_IDLIB_LIST_MENU > values; 564 idStr btnLabel; 565 idStr description; 566 animState_t animState; 567 const idMaterial * img; 568 idSWFScriptFunction * scriptFunction; 569 bool ignoreColor; 570 }; 571 572 /* 573 ================================================ 574 idMenuWidget_LobbyButton 575 ================================================ 576 */ 577 class idMenuWidget_LobbyButton : public idMenuWidget_Button { 578 public: 579 idMenuWidget_LobbyButton() : 580 voiceState( VOICECHAT_DISPLAY_NONE ) { 581 } 582 583 virtual void Update(); 584 void SetButtonInfo( idStr name_, voiceStateDisplay_t voiceState_ ); 585 bool IsValid() { return !name.IsEmpty(); } 586 587 protected: 588 idStr name; 589 voiceStateDisplay_t voiceState; 590 }; 591 592 /* 593 ================================================ 594 idMenuWidget_ScoreboardButton 595 ================================================ 596 */ 597 class idMenuWidget_ScoreboardButton : public idMenuWidget_Button { 598 public: 599 idMenuWidget_ScoreboardButton() : 600 voiceState( VOICECHAT_DISPLAY_NONE ), 601 index( -1 ) { 602 } 603 604 virtual void Update(); 605 void SetButtonInfo( int index_, idList< idStr > & list, voiceStateDisplay_t voiceState_ ); 606 607 protected: 608 voiceStateDisplay_t voiceState; 609 int index; 610 }; 611 612 /* 613 ================================================ 614 idMenuWidget_ControlButton 615 ================================================ 616 */ 617 class idMenuWidget_ControlButton : public idMenuWidget_Button { 618 public: 619 idMenuWidget_ControlButton() : 620 optionType( OPTION_BUTTON_TEXT ), 621 disabled( false ) { 622 } 623 624 virtual void Update(); 625 void SetOptionType( const menuOption_t type ) { optionType = type; } 626 menuOption_t GetOptionType() const { return optionType; } 627 void SetupEvents( int delay, int index ); 628 void SetDisabled( bool disable ) { disabled = disable; } 629 630 protected: 631 menuOption_t optionType; 632 bool disabled; 633 }; 634 635 /* 636 ================================================ 637 idMenuWidget_ServerButton 638 ================================================ 639 */ 640 class idMenuWidget_ServerButton : public idMenuWidget_Button { 641 public: 642 643 idMenuWidget_ServerButton() : 644 players( 0 ), 645 index( 0 ), 646 maxPlayers( 0 ), 647 joinable( false ), 648 validMap( false ) { 649 } 650 651 virtual void Update(); 652 void SetButtonInfo( idStr name_, idStrId mapName_, idStr modeName_, int index_ = 0, int players_ = 0, int maxPlayers_ = 0, bool joinable_ = false, bool validMap_ = false ); 653 bool IsValid() { return !serverName.IsEmpty(); } 654 bool CanJoin() { return ( joinable && validMap ); } 655 656 protected: 657 idStr serverName; 658 int index; 659 int players; 660 int maxPlayers; 661 bool joinable; 662 bool validMap; 663 idStrId mapName; 664 idStr modeName; 665 }; 666 667 /* 668 ================================================ 669 idMenuWidget_NavButton 670 ================================================ 671 */ 672 class idMenuWidget_NavButton : public idMenuWidget_Button { 673 public: 674 675 enum navWidgetState_t { 676 NAV_WIDGET_LEFT, // option on left side 677 NAV_WIDGET_RIGHT, // option on right side 678 NAV_WIDGET_SELECTED // option is selected 679 }; 680 681 idMenuWidget_NavButton() : 682 navIndex( 0 ), 683 xPos( 0 ) { 684 } 685 686 virtual bool ExecuteEvent( const idWidgetEvent & event ); 687 virtual void Update(); 688 689 void SetNavIndex( int i, const navWidgetState_t type ) { navIndex = i; navState = type; } 690 void SetPosition( float pos ) { xPos = pos; } 691 692 private: 693 694 int navIndex; 695 float xPos; 696 navWidgetState_t navState; 697 698 }; 699 700 /* 701 ================================================ 702 idMenuWidget_NavButton 703 ================================================ 704 */ 705 class idMenuWidget_MenuButton : public idMenuWidget_Button { 706 public: 707 708 idMenuWidget_MenuButton() : 709 xPos( 0 ) { 710 } 711 712 virtual void Update(); 713 void SetPosition( float pos ) { xPos = pos; } 714 715 private: 716 717 float xPos; 718 719 }; 720 721 /* 722 ================================================ 723 idMenuWidget_List 724 725 Stores a list of widgets but displays only a segment of them at a time. 726 ================================================ 727 */ 728 class idMenuWidget_List : public idMenuWidget { 729 public: 730 idMenuWidget_List() : 731 numVisibleOptions( 0 ), 732 viewOffset( 0 ), 733 viewIndex( 0 ), 734 allowWrapping( false ) { 735 736 } 737 738 virtual void Update(); 739 virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false ); 740 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 741 virtual void Scroll( const int scrollIndexAmount, const bool wrapAround = false ); 742 virtual void ScrollOffset( const int scrollIndexAmount ); 743 virtual int GetTotalNumberOfOptions() const { return GetChildren().Num(); } 744 virtual bool PrepareListElement( idMenuWidget & widget, const int childIndex ) { return true; } 745 746 bool IsWrappingAllowed() const { return allowWrapping; } 747 void SetWrappingAllowed( const bool allow ) { allowWrapping = allow; } 748 749 void SetNumVisibleOptions( const int numVisibleOptions_ ) { numVisibleOptions = numVisibleOptions_; } 750 int GetNumVisibleOptions() const { return numVisibleOptions; } 751 752 int GetViewOffset() const { return viewOffset; } 753 void SetViewOffset( const int offset ) { viewOffset = offset; } 754 755 int GetViewIndex() const { return viewIndex; } 756 void SetViewIndex( const int index ) { viewIndex = index; } 757 758 void CalculatePositionFromIndexDelta( int & outIndex, int & outOffset, const int currentIndex, const int currentOffset, const int windowSize, const int maxSize, const int indexDelta, const bool allowWrapping, const bool wrapAround = false ) const; 759 void CalculatePositionFromOffsetDelta( int & outIndex, int & outOffset, const int currentIndex, const int currentOffset, const int windowSize, const int maxSize, const int offsetDelta ) const; 760 761 private: 762 int numVisibleOptions; 763 int viewOffset; 764 int viewIndex; 765 bool allowWrapping; 766 }; 767 768 class idBrowserEntry_t { 769 public: 770 idStr serverName; 771 int index; 772 int players; 773 int maxPlayers; 774 bool joinable; 775 bool validMap; 776 idStrId mapName; 777 idStr modeName; 778 }; 779 780 /* 781 ================================================ 782 idMenuWidget_GameBrowserList 783 ================================================ 784 */ 785 class idMenuWidget_GameBrowserList : public idMenuWidget_List { 786 public: 787 virtual void Update(); 788 virtual bool PrepareListElement( idMenuWidget & widget, const int childIndex ); 789 virtual int GetTotalNumberOfOptions() const; 790 void ClearGames(); 791 void AddGame( idStr name_, idStrId mapName_, idStr modeName_, int index_ = 0, int players_ = 0, int maxPlayers_ = 0, bool joinable_ = false, bool validMap_ = false ); 792 int GetServerIndex(); 793 private: 794 idList< idBrowserEntry_t > games; 795 }; 796 797 /* 798 ================================================ 799 idMenuWidget_Carousel 800 Displays a list of items in a looping carousel pattern 801 ================================================ 802 */ 803 class idMenuWidget_Carousel : public idMenuWidget { 804 public: 805 806 idMenuWidget_Carousel() : 807 numVisibleOptions( 0 ), 808 viewIndex( 0 ), 809 moveToIndex( 0 ), 810 scrollLeft( false ), 811 fastScroll( false ), 812 moveDiff( 0 ) { 813 } 814 815 virtual void Initialize( idMenuHandler * data ); 816 virtual void Update(); 817 virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false ); 818 virtual int GetTotalNumberOfOptions() const { return imgList.Num(); } 819 virtual bool PrepareListElement( idMenuWidget & widget, const int childIndex ) { return true; } 820 821 void SetNumVisibleOptions( const int numVisibleOptions_ ) { numVisibleOptions = numVisibleOptions_; } 822 int GetNumVisibleOptions() const { return numVisibleOptions; } 823 824 void MoveToIndex( int index, bool instant = false ); 825 void MoveToFirstItem( bool instant = true ); 826 void MoveToLastItem( bool instant = true ); 827 int GetMoveToIndex() { return moveToIndex; } 828 void SetMoveToIndex( int index ) { moveToIndex = index; } 829 void SetViewIndex( int index ) { viewIndex = index; } 830 int GetViewIndex() const { return viewIndex; } 831 void SetListImages( idList<const idMaterial *> & list ); 832 void SetMoveDiff( int val ) { moveDiff = val; } 833 int GetMoveDiff() { return moveDiff; } 834 bool GetScrollLeft() { return scrollLeft; } 835 836 private: 837 838 int numVisibleOptions; 839 int viewIndex; 840 int moveToIndex; 841 int moveDiff; 842 bool fastScroll; 843 bool scrollLeft; 844 idList<const idMaterial *> imgList; 845 846 }; 847 848 /* 849 ================================================ 850 idMenuWidget_Help 851 852 Knows how to display help tooltips by observing events from other widgets 853 ================================================ 854 */ 855 class idMenuWidget_Help : public idMenuWidget { 856 public: 857 virtual void Update(); 858 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 859 860 private: 861 idStr lastFocusedMessage; // message from last widget that had focus 862 idStr lastHoveredMessage; // message from last widget that was hovered over 863 bool hideMessage; 864 }; 865 866 /* 867 ================================================ 868 idMenuWidget_CommandBar 869 ================================================ 870 */ 871 class idMenuWidget_CommandBar : public idMenuWidget { 872 public: 873 enum button_t { 874 BUTTON_JOY1, 875 BUTTON_JOY2, 876 BUTTON_JOY3, 877 BUTTON_JOY4, 878 BUTTON_JOY10, 879 BUTTON_TAB, 880 MAX_BUTTONS 881 }; 882 883 enum alignment_t { 884 LEFT, 885 RIGHT 886 }; 887 888 struct buttonInfo_t { 889 idStr label; // empty labels are treated as hidden buttons 890 idWidgetAction action; 891 }; 892 893 idMenuWidget_CommandBar() : 894 alignment( LEFT ) { 895 896 buttons.SetNum( MAX_BUTTONS ); 897 } 898 899 virtual void Update(); 900 virtual bool ExecuteEvent( const idWidgetEvent & event ); 901 902 buttonInfo_t * GetButton( const button_t button ) { return &buttons[ button ]; } 903 void ClearAllButtons(); 904 905 alignment_t GetAlignment() const { return alignment; } 906 void SetAlignment( const alignment_t alignment_ ) { alignment = alignment_; } 907 908 private: 909 idStaticList< buttonInfo_t, MAX_BUTTONS > buttons; 910 alignment_t alignment; 911 }; 912 913 /* 914 ================================================ 915 idMenuWidget_DynamicList 916 ================================================ 917 */ 918 class idMenuWidget_LobbyList : public idMenuWidget_List { 919 public: 920 idMenuWidget_LobbyList() : 921 numEntries( 0 ) { 922 } 923 924 virtual void Update(); 925 virtual bool PrepareListElement( idMenuWidget & widget, const int childIndex ); 926 virtual int GetTotalNumberOfOptions() const { return numEntries; } 927 void SetEntryData( int index, idStr name, voiceStateDisplay_t voiceState ); 928 void SetHeadingInfo( idList< idStr > & list ); 929 void SetNumEntries( int num ) { numEntries = num; } 930 int GetNumEntries() { return numEntries; } 931 void SetRefreshFunction( const char* func ); 932 private: 933 idList< idStr, TAG_IDLIB_LIST_MENU > headings; 934 int numEntries; 935 }; 936 937 /* 938 ================================================ 939 idMenuWidget_DynamicList 940 ================================================ 941 */ 942 class idMenuWidget_DynamicList : public idMenuWidget_List { 943 public: 944 945 idMenuWidget_DynamicList() : 946 controlList( false ), 947 ignoreColor( false ) { 948 } 949 950 virtual void Update(); 951 virtual void Initialize( idMenuHandler * data ); 952 virtual int GetTotalNumberOfOptions() const; 953 virtual bool PrepareListElement( idMenuWidget & widget, const int childIndex ); 954 955 virtual void Recalculate(); 956 virtual void SetListData( idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > & list ); 957 958 void SetControlList( bool val ) { controlList = val; } 959 void SetIgnoreColor( bool val ) { ignoreColor = val; } 960 961 protected: 962 idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > listItemInfo; 963 bool controlList; 964 bool ignoreColor; 965 }; 966 967 /* 968 ================================================ 969 idMenuWidget_ScoreboardList 970 ================================================ 971 */ 972 class idMenuWidget_ScoreboardList : public idMenuWidget_DynamicList { 973 public: 974 virtual void Update(); 975 virtual int GetTotalNumberOfOptions() const; 976 }; 977 978 /* 979 ================================================ 980 idMenuWidget_NavBar 981 982 The nav bar is set up with the main option being at the safe frame line. 983 ================================================ 984 */ 985 class idMenuWidget_NavBar : public idMenuWidget_DynamicList { 986 public: 987 988 idMenuWidget_NavBar() : 989 initialPos( 0.0f ), 990 buttonPos( 0.0f ), 991 leftSpacer( 0.0f ), 992 rightSpacer( 0.0f ), 993 selectedSpacer( 0.0f ) { 994 } 995 996 virtual void Update(); 997 virtual void Initialize( idMenuHandler * data ); 998 virtual void SetInitialXPos( float pos ) { initialPos = pos; } 999 virtual void SetButtonSpacing( float lSpace, float rSpace, float sSpace ) { leftSpacer = lSpace; rightSpacer = rSpace; selectedSpacer = sSpace; } 1000 virtual bool PrepareListElement( idMenuWidget & widget, const int navIndex ); 1001 virtual void SetListHeadings( idList< idStr > & list ); 1002 virtual int GetTotalNumberOfOptions() const; 1003 1004 private: 1005 1006 idList< idStr, TAG_IDLIB_LIST_MENU > headings; 1007 float initialPos; 1008 float buttonPos; 1009 float leftSpacer; 1010 float rightSpacer; 1011 float selectedSpacer; 1012 1013 }; 1014 1015 /* 1016 ================================================ 1017 idMenuWidget_NavBar 1018 1019 The nav bar is set up with the main option being at the safe frame line. 1020 ================================================ 1021 */ 1022 class idMenuWidget_MenuBar : public idMenuWidget_DynamicList { 1023 public: 1024 1025 idMenuWidget_MenuBar() : 1026 totalWidth( 0.0f ), 1027 buttonPos( 0.0f ), 1028 rightSpacer( 0.0f ) { 1029 } 1030 1031 virtual void Update(); 1032 virtual void Initialize( idMenuHandler * data ); 1033 virtual void SetButtonSpacing( float rSpace ) { rightSpacer = rSpace; } 1034 virtual bool PrepareListElement( idMenuWidget & widget, const int navIndex ); 1035 virtual void SetListHeadings( idList< idStr > & list ); 1036 virtual int GetTotalNumberOfOptions() const; 1037 1038 private: 1039 1040 idList< idStr, TAG_IDLIB_LIST_MENU > headings; 1041 float totalWidth; 1042 float buttonPos; 1043 float rightSpacer; 1044 1045 }; 1046 1047 /* 1048 ================================================ 1049 idMenuWidget_PDA_UserData 1050 ================================================ 1051 */ 1052 class idMenuWidget_PDA_UserData : public idMenuWidget { 1053 public: 1054 idMenuWidget_PDA_UserData() : 1055 pdaIndex( 0 ) { 1056 } 1057 virtual ~idMenuWidget_PDA_UserData() {} 1058 virtual void Update(); 1059 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 1060 1061 private: 1062 int pdaIndex; 1063 }; 1064 1065 /* 1066 ================================================ 1067 idMenuWidget_DynamicList 1068 ================================================ 1069 */ 1070 class idMenuWidget_ScrollBar : public idMenuWidget { 1071 public: 1072 idMenuWidget_ScrollBar() : 1073 yTop( 0.0f ), 1074 yBot( 0.0f ), 1075 dragging( false ) { 1076 } 1077 1078 virtual void Initialize( idMenuHandler * data ); 1079 virtual void Update(); 1080 virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false ); 1081 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 1082 1083 void CalcTopAndBottom(); 1084 void CalculatePosition( float x, float y ); 1085 1086 float yTop; 1087 float yBot; 1088 bool dragging; 1089 }; 1090 1091 /* 1092 ================================================ 1093 idMenuWidget_InfoBox 1094 ================================================ 1095 */ 1096 class idMenuWidget_InfoBox: public idMenuWidget { 1097 public: 1098 idMenuWidget_InfoBox() : 1099 scrollbar( NULL ) { 1100 } 1101 1102 virtual void Initialize( idMenuHandler * data ); 1103 virtual void Update(); 1104 virtual bool HandleAction( idWidgetAction & action, const idWidgetEvent & event, idMenuWidget * widget, bool forceHandled = false ); 1105 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 1106 void SetHeading( idStr val ) { heading = val; } 1107 void SetBody( idStr val ) { info = val; } 1108 void ResetInfoScroll(); 1109 void Scroll( int d ); 1110 int GetScroll(); 1111 int GetMaxScroll(); 1112 void SetScroll( int scroll ); 1113 void SetScrollbar( idMenuWidget_ScrollBar * bar ); 1114 private: 1115 idMenuWidget_ScrollBar * scrollbar; 1116 idStr heading; 1117 idStr info; 1118 }; 1119 1120 /* 1121 ================================================ 1122 idMenuWidget_PDA_Objective 1123 ================================================ 1124 */ 1125 class idMenuWidget_PDA_Objective: public idMenuWidget { 1126 public: 1127 idMenuWidget_PDA_Objective() : 1128 pdaIndex( 0 ) { 1129 } 1130 virtual void Update(); 1131 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 1132 private: 1133 int pdaIndex; 1134 }; 1135 1136 /* 1137 ================================================ 1138 idMenuWidget_Shell_SaveInfo 1139 ================================================ 1140 */ 1141 class idMenuWidget_Shell_SaveInfo: public idMenuWidget { 1142 public: 1143 idMenuWidget_Shell_SaveInfo() : 1144 loadIndex( 0 ), 1145 forSaveScreen( false ) { 1146 } 1147 virtual void Update(); 1148 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 1149 1150 void SetForSaveScreen( bool val ) { forSaveScreen = val; } 1151 private: 1152 int loadIndex; 1153 bool forSaveScreen; 1154 }; 1155 1156 /* 1157 ================================================ 1158 idMenuWidget_PDA_AudioFiles 1159 ================================================ 1160 */ 1161 class idMenuWidget_PDA_AudioFiles: public idMenuWidget { 1162 public: 1163 idMenuWidget_PDA_AudioFiles() : 1164 pdaIndex( 0 ) { 1165 } 1166 virtual ~idMenuWidget_PDA_AudioFiles(); 1167 virtual void Update(); 1168 virtual void Initialize( idMenuHandler * data ); 1169 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 1170 private: 1171 int pdaIndex; 1172 idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > audioFileNames; 1173 }; 1174 1175 /* 1176 ================================================ 1177 idMenuWidget_PDA_AudioFiles 1178 ================================================ 1179 */ 1180 class idMenuWidget_PDA_EmailInbox: public idMenuWidget { 1181 public: 1182 idMenuWidget_PDA_EmailInbox() : 1183 pdaIndex( 0 ), 1184 emailList( NULL ), 1185 scrollbar( NULL ) { 1186 } 1187 virtual void Update(); 1188 virtual void Initialize( idMenuHandler * data ); 1189 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 1190 1191 idMenuWidget_DynamicList * GetEmailList() { return emailList; } 1192 idMenuWidget_ScrollBar * GetScrollbar() { return scrollbar; } 1193 private: 1194 idMenuWidget_DynamicList * emailList; 1195 idMenuWidget_ScrollBar * scrollbar; 1196 int pdaIndex; 1197 idList< idList< idStr, TAG_IDLIB_LIST_MENU >, TAG_IDLIB_LIST_MENU > emailInfo; 1198 }; 1199 1200 /* 1201 ================================================ 1202 idMenuWidget_PDA_AudioFiles 1203 ================================================ 1204 */ 1205 class idMenuWidget_ItemAssignment: public idMenuWidget { 1206 public: 1207 idMenuWidget_ItemAssignment() : 1208 slotIndex( 0 ) { 1209 } 1210 1211 virtual void Update(); 1212 void SetIcon( int index, const idMaterial * icon ); 1213 void FindFreeSpot(); 1214 int GetSlotIndex() { return slotIndex; } 1215 void SetSlotIndex( int num ) { slotIndex = num; } 1216 private: 1217 const idMaterial * images[ NUM_QUICK_SLOTS ]; 1218 int slotIndex; 1219 1220 }; 1221 1222 1223 /* 1224 ================================================ 1225 idMenuWidget_PDA_AudioFiles 1226 ================================================ 1227 */ 1228 class idMenuWidget_PDA_VideoInfo: public idMenuWidget { 1229 public: 1230 virtual void Update(); 1231 virtual void ObserveEvent( const idMenuWidget & widget, const idWidgetEvent & event ); 1232 private: 1233 int videoIndex; 1234 }; 1235 1236 1237 /* 1238 ================================================ 1239 idWidgetActionHandler 1240 ================================================ 1241 */ 1242 class idWidgetActionHandler : public idSWFScriptFunction_RefCounted { 1243 public: 1244 idWidgetActionHandler( idMenuWidget * widget, actionHandler_t actionEventType, widgetEvent_t _event ) : 1245 targetWidget( widget ), 1246 type( actionEventType ), 1247 targetEvent( _event ) { 1248 1249 } 1250 1251 idSWFScriptVar Call( idSWFScriptObject * thisObject, const idSWFParmList & parms ) { 1252 1253 idWidgetAction action; 1254 bool handled = false; 1255 switch ( type ) { 1256 case WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER: { 1257 action.Set( (widgetAction_t)WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_VERTICAL, 1 ); 1258 handled = true; 1259 break; 1260 } 1261 case WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER: { 1262 action.Set( (widgetAction_t)WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_VERTICAL, -1 ); 1263 handled = true; 1264 break; 1265 } 1266 case WIDGET_ACTION_EVENT_SCROLL_DOWN_START_REPEATER_VARIABLE: { 1267 action.Set( (widgetAction_t)WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_VERTICAL_VARIABLE, 1 ); 1268 handled = true; 1269 break; 1270 } 1271 case WIDGET_ACTION_EVENT_SCROLL_UP_START_REPEATER_VARIABLE: { 1272 action.Set( (widgetAction_t)WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_VERTICAL_VARIABLE, -1 ); 1273 handled = true; 1274 break; 1275 } 1276 case WIDGET_ACTION_EVENT_SCROLL_PAGE_DOWN_START_REPEATER: { 1277 action.Set( (widgetAction_t)WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_PAGE, 1 ); 1278 handled = true; 1279 break; 1280 } 1281 case WIDGET_ACTION_EVENT_SCROLL_PAGE_UP_START_REPEATER: { 1282 action.Set( (widgetAction_t)WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_PAGE, -1 ); 1283 handled = true; 1284 break; 1285 } 1286 case WIDGET_ACTION_EVENT_STOP_REPEATER: { 1287 action.Set( (widgetAction_t)WIDGET_ACTION_STOP_REPEATER ); 1288 handled = true; 1289 break; 1290 } 1291 case WIDGET_ACTION_EVENT_TAB_NEXT: { 1292 action.Set( (widgetAction_t)WIDGET_ACTION_SCROLL_TAB, 1 ); 1293 handled = true; 1294 break; 1295 } 1296 case WIDGET_ACTION_EVENT_TAB_PREV: { 1297 action.Set( (widgetAction_t)WIDGET_ACTION_SCROLL_TAB, -1 ); 1298 handled = true; 1299 break; 1300 } 1301 case WIDGET_ACTION_EVENT_JOY3_ON_PRESS: { 1302 action.Set( (widgetAction_t)WIDGET_ACTION_JOY3_ON_PRESS ); 1303 handled = true; 1304 break; 1305 } 1306 case WIDGET_ACTION_EVENT_SCROLL_LEFT_START_REPEATER: { 1307 action.Set( (widgetAction_t)WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_HORIZONTAL, -1 ); 1308 handled = true; 1309 break; 1310 } 1311 case WIDGET_ACTION_EVENT_SCROLL_RIGHT_START_REPEATER: { 1312 action.Set( (widgetAction_t)WIDGET_ACTION_START_REPEATER, WIDGET_ACTION_SCROLL_HORIZONTAL, 1 ); 1313 handled = true; 1314 break; 1315 } 1316 case WIDGET_ACTION_EVENT_DRAG_START: { 1317 action.Set( (widgetAction_t)WIDGET_ACTION_SCROLL_DRAG ); 1318 handled = true; 1319 break; 1320 } 1321 case WIDGET_ACTION_EVENT_DRAG_STOP: { 1322 action.Set( (widgetAction_t)WIDGET_ACTION_EVENT_DRAG_STOP ); 1323 handled = true; 1324 break; 1325 } 1326 } 1327 1328 if ( handled ) { 1329 targetWidget->HandleAction( action, idWidgetEvent( targetEvent, 0, thisObject, parms ), targetWidget ); 1330 } 1331 1332 return idSWFScriptVar(); 1333 } 1334 1335 private: 1336 idMenuWidget * targetWidget; 1337 actionHandler_t type; 1338 widgetEvent_t targetEvent; 1339 }; 1340 1341 #endif