| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- /*
- ** Command & Conquer Generals Zero Hour(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** 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 3 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, see <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- // FILE: ExtendedMessageBox.cpp ///////////////////////////////////////////////////////////////////
- // Author: Matt Campbell, January 2003
- // Description: We go quiet in 1 day, gold in 15. Poor time to rewrite message boxes, so
- // we get this file instead. Phooey.
- ///////////////////////////////////////////////////////////////////////////////////////////////////
- // SYSTEM INCLUDES ////////////////////////////////////////////////////////////
- // USER INCLUDES //////////////////////////////////////////////////////////////
- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
- #include "Common/GameEngine.h"
- #include "Common/NameKeyGenerator.h"
- #include "GameClient/WindowLayout.h"
- #include "GameClient/Gadget.h"
- #include "GameClient/Shell.h"
- #include "GameClient/KeyDefs.h"
- #include "GameClient/GadgetStaticText.h"
- #include "GameClient/GameWindowManager.h"
- #include "GameClient/ExtendedMessageBox.h"
- WindowMsgHandledType ExtendedMessageBoxSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 );
- //-------------------------------------------------------------------------------------------------
- /** Create an extended Modal Message Box */
- //-------------------------------------------------------------------------------------------------
- static GameWindow *gogoExMessageBox(Int x, Int y, Int width, Int height, UnsignedShort buttonFlags,
- UnicodeString titleString, UnicodeString bodyString, void *userData,
- MessageBoxFunc yesCallback,
- MessageBoxFunc noCallback,
- MessageBoxFunc okCallback,
- MessageBoxFunc cancelCallback )
- {
- // first check to make sure we have some buttons to display
- if(buttonFlags == 0 )
- {
- return NULL;
- }
- GameWindow *parent = TheWindowManager->winCreateFromScript( AsciiString("Menus/MessageBox.wnd") );
- TheWindowManager->winSetModal( parent );
- TheWindowManager->winSetFocus( NULL ); // make sure we lose focus from other windows even if we refuse focus ourselves
- TheWindowManager->winSetFocus( parent );
- // If the user wants the size to be different then the default
- float ratioX, ratioY = 1;
- if( width > 0 && height > 0 )
- {
- ICoord2D temp;
- //First grab the percent increase/decrease compaired to the default size
- parent->winGetSize( &temp.x, &temp.y);
- ratioX = (float)width / (float)temp.x;
- ratioY = (float)height / (float)temp.y;
- //Set the window's new size
- parent->winSetSize( width, height);
-
- //Resize/reposition all the children windows based off the ratio
- GameWindow *child;
- for( child = parent->winGetChild(); child; child = child->winGetNext() )
- {
- child->winGetSize(&temp.x, &temp.y);
- temp.x =Int(temp.x * ratioX);
- temp.y =Int(temp.y * ratioY);
- child->winSetSize(temp.x, temp.y);
- child->winGetPosition(&temp.x, &temp.y);
- temp.x =Int(temp.x * ratioX);
- temp.y =Int(temp.y * ratioY);
- child->winSetPosition(temp.x, temp.y);
- }
- }
-
- // If the user wants to position the message box somewhere other then default
- if( x >= 0 && y >= 0)
- parent->winSetPosition(x, y);
-
- // Reposition the buttons
- Int buttonX[3], buttonY[3];
-
- //In the layout, buttonOk will be in the first button position
- NameKeyType buttonOkID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:ButtonOk" ) );
- GameWindow *buttonOk = TheWindowManager->winGetWindowFromId(parent, buttonOkID);
- buttonOk->winGetPosition(&buttonX[0], &buttonY[0]);
- NameKeyType buttonYesID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:ButtonYes" ) );
- GameWindow *buttonYes = TheWindowManager->winGetWindowFromId(parent, buttonYesID);
- //buttonNo in the second position
- NameKeyType buttonNoID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:ButtonNo" ) );
- GameWindow *buttonNo = TheWindowManager->winGetWindowFromId(parent, buttonNoID);
- buttonNo->winGetPosition(&buttonX[1], &buttonY[1]);
-
- //and buttonCancel in the third
- NameKeyType buttonCancelID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:ButtonCancel" ) );
- GameWindow *buttonCancel = TheWindowManager->winGetWindowFromId(parent, buttonCancelID);
- buttonCancel->winGetPosition(&buttonX[2], &buttonY[2]);
-
- //we shouldn't have button OK and Yes on the same dialog
- if((buttonFlags & (MSG_BOX_OK | MSG_BOX_YES)) == (MSG_BOX_OK | MSG_BOX_YES) )
- {
- DEBUG_ASSERTCRASH(false, ("Passed in MSG_BOX_OK and MSG_BOX_YES. Big No No."));
- }
-
- //Position the OK button if we have one
- if( (buttonFlags & MSG_BOX_OK) == MSG_BOX_OK)
- {
- buttonOk->winSetPosition(buttonX[0], buttonY[0]);
- buttonOk->winHide(FALSE);
- }
- else if( (buttonFlags & MSG_BOX_YES) == MSG_BOX_YES)
- {
- //Position the Yes if we have one
- buttonYes->winSetPosition(buttonX[0], buttonY[0]);
- buttonYes->winHide(FALSE);
- }
-
- if((buttonFlags & (MSG_BOX_NO | MSG_BOX_CANCEL)) == (MSG_BOX_NO | MSG_BOX_CANCEL) )
- {
- //If we have both the No and Cancel button, then the no should go in the middle position
- buttonNo->winSetPosition(buttonX[1], buttonY[1]);
- buttonCancel->winSetPosition(buttonX[2], buttonY[2]);
- buttonNo->winHide(FALSE);
- buttonCancel->winHide(FALSE);
- }
- else if( (buttonFlags & MSG_BOX_NO) == MSG_BOX_NO)
- {
- //if we just have the no button, then position it in the right most spot
- buttonNo->winSetPosition(buttonX[2], buttonY[2]);
- buttonNo->winHide(FALSE);
- }
- else if( (buttonFlags & MSG_BOX_CANCEL) == MSG_BOX_CANCEL)
- {
- //else if we just have the Cancel button, well, it should always go in the right spot
- buttonCancel->winSetPosition(buttonX[2], buttonY[2]);
- buttonCancel->winHide(FALSE);
- }
-
- // Fill the text into the text boxes
- NameKeyType staticTextTitleID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:StaticTextTitle" ) );
- GameWindow *staticTextTitle = TheWindowManager->winGetWindowFromId(parent, staticTextTitleID);
- GadgetStaticTextSetText(staticTextTitle,titleString);
-
- NameKeyType staticTextMessageID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:StaticTextMessage" ) );
- GameWindow *staticTextMessage = TheWindowManager->winGetWindowFromId(parent, staticTextMessageID);
- GadgetStaticTextSetText(staticTextMessage,bodyString);
- // create a structure that will pass the functions to
- WindowExMessageBoxData *MsgBoxCallbacks = NEW WindowExMessageBoxData;
- MsgBoxCallbacks->cancelCallback = cancelCallback;
- MsgBoxCallbacks->noCallback = noCallback;
- MsgBoxCallbacks->okCallback = okCallback;
- MsgBoxCallbacks->yesCallback = yesCallback;
- MsgBoxCallbacks->userData = userData;
- //pass the structure to the dialog
- parent->winSetUserData( MsgBoxCallbacks );
- parent->winSetSystemFunc(ExtendedMessageBoxSystem);
-
- //make sure the dialog is showing and bring it to the top
- parent->winHide(FALSE);
- parent->winBringToTop();
-
- return parent;
- }// gogoExMessageBox
- GameWindow *ExMessageBoxYesNo (UnicodeString titleString,UnicodeString bodyString, void *userData,
- MessageBoxFunc yesCallback, MessageBoxFunc noCallback)
- {
- return gogoExMessageBox(-1,-1,-1,-1,MSG_BOX_NO | MSG_BOX_YES , titleString, bodyString, userData, yesCallback, noCallback, NULL, NULL);
- }
- GameWindow *ExMessageBoxYesNoCancel (UnicodeString titleString,UnicodeString bodyString, void *userData,
- MessageBoxFunc yesCallback, MessageBoxFunc noCallback, MessageBoxFunc cancelCallback)
- {
- return gogoExMessageBox(-1,-1,-1,-1,MSG_BOX_NO | MSG_BOX_YES | MSG_BOX_CANCEL , titleString, bodyString, userData, yesCallback, noCallback, NULL, cancelCallback);
- }
- GameWindow *ExMessageBoxOkCancel (UnicodeString titleString,UnicodeString bodyString, void *userData,
- MessageBoxFunc okCallback, MessageBoxFunc cancelCallback)
- {
- return gogoExMessageBox(-1,-1,-1,-1,MSG_BOX_OK | MSG_BOX_CANCEL , titleString, bodyString, userData, NULL, NULL, okCallback, cancelCallback);
- }
- GameWindow *ExMessageBoxOk (UnicodeString titleString,UnicodeString bodyString, void *userData,
- MessageBoxFunc okCallback)
- {
- return gogoExMessageBox(-1,-1,-1,-1,MSG_BOX_OK, titleString, bodyString, userData, NULL, NULL, okCallback, NULL);
- }
- GameWindow *ExMessageBoxCancel (UnicodeString titleString,UnicodeString bodyString, void *userData,
- MessageBoxFunc cancelCallback)
- {
- return gogoExMessageBox(-1,-1,-1,-1, MSG_BOX_CANCEL, titleString, bodyString, userData, NULL, NULL, NULL, cancelCallback);
- }
- // PRIVATE DATA ///////////////////////////////////////////////////////////////////////////////////
- //-------------------------------------------------------------------------------------------------
- /** Message Box window system callback */
- //-------------------------------------------------------------------------------------------------
- WindowMsgHandledType ExtendedMessageBoxSystem( GameWindow *window, UnsignedInt msg,
- WindowMsgData mData1, WindowMsgData mData2 )
- {
-
-
- switch( msg )
- {
- //---------------------------------------------------------------------------------------------
- case GWM_DESTROY:
- {
- delete (WindowExMessageBoxData *)window->winGetUserData();
- window->winSetUserData( NULL );
- break;
- } // end case
- // --------------------------------------------------------------------------------------------
- case GWM_INPUT_FOCUS:
- {
- // if we're givin the opportunity to take the keyboard focus we must say we want it
- if( mData1 == TRUE )
- *(Bool *)mData2 = TRUE;
- break;
- } // end input
- //---------------------------------------------------------------------------------------------
- case GBM_SELECTED:
- {
- GameWindow *control = (GameWindow *)mData1;
- Int controlID = control->winGetWindowId();
- static NameKeyType buttonOkID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:ButtonOk" ) );
- static NameKeyType buttonYesID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:ButtonYes" ) );
- static NameKeyType buttonNoID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:ButtonNo" ) );
- static NameKeyType buttonCancelID = TheNameKeyGenerator->nameToKey( AsciiString( "MessageBox.wnd:ButtonCancel" ) );
- WindowExMessageBoxData *MsgBoxCallbacks = (WindowExMessageBoxData *)window->winGetUserData();
- MessageBoxReturnType ret = MB_RETURN_CLOSE;
- if( controlID == buttonOkID )
- {
- if (MsgBoxCallbacks->okCallback)
- ret = MsgBoxCallbacks->okCallback(MsgBoxCallbacks->userData);
- } // end if
- else if( controlID == buttonYesID )
- {
- if (MsgBoxCallbacks->yesCallback)
- ret = MsgBoxCallbacks->yesCallback(MsgBoxCallbacks->userData);
- } // end else if
- else if( controlID == buttonNoID )
- {
- if (MsgBoxCallbacks->noCallback)
- ret = MsgBoxCallbacks->noCallback(MsgBoxCallbacks->userData);
- } // end else if
- else if( controlID == buttonCancelID )
- {
- if (MsgBoxCallbacks->cancelCallback)
- ret = MsgBoxCallbacks->cancelCallback(MsgBoxCallbacks->userData);
- } // end else if
- if (ret == MB_RETURN_CLOSE)
- TheWindowManager->winDestroy(window);
-
- break;
- } // end selected
-
- //---------------------------------------------------------------------------------------------
- default:
- return MSG_IGNORED;
- } // end switch
- return MSG_HANDLED;
- } // end ExtendedMessageBoxSystem
|