| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- //
- // Copyright 2020 Electronic Arts Inc.
- //
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
- // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
- // in the hope that it will be useful, but with permitted additional restrictions
- // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
- // distributed with this program. You should have received a copy of the
- // GNU General Public License along with permitted additional restrictions
- // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
- #ifdef WOLAPI_INTEGRATION
- // SEditDlg.cpp - "SimpleEditDlgClass": An ok/cancel type dialog with 1 or 2 edit boxes.
- // Mostly a hack for what I need right now - not necessarily very flexible.
- // Still - I can't believe there isn't a set of dialog classes in here already.
- // ajw 07/21/98
- #include "SEditDlg.h"
- #include "WOLEdit.h"
- extern bool cancel_current_msgbox;
- bool disable_current_msgbox = false;
- //***********************************************************************************************
- SimpleEditDlgClass::SimpleEditDlgClass( int iDialogWidth, const char* szTitle, const char* szPrompt, int iEditCharsAccept,
- const char* szPrompt2 /* = NULL */, int iEditCharsAccept2 /* = 0 */ )
- : iDialogWidth( iDialogWidth ), iEditCharsAccept( iEditCharsAccept ), iEditCharsAccept2( iEditCharsAccept2 )
- {
- // Copy strings.
- if( szTitle )
- {
- this->szTitle = new char[ strlen( szTitle ) + 1 ];
- strcpy( this->szTitle, szTitle );
- }
- else
- this->szTitle = NULL;
- if( szPrompt )
- {
- this->szPrompt = new char[ strlen( szPrompt ) + 1 ];
- strcpy( this->szPrompt, szPrompt );
- }
- else
- this->szPrompt = NULL; // I wouldn't try this ... not totally implemented.
- if( szPrompt2 )
- {
- this->szPrompt2 = new char[ strlen( szPrompt2 ) + 1 ];
- strcpy( this->szPrompt2, szPrompt2 );
- }
- else
- this->szPrompt2 = NULL; // This is the flag for whether or not there is a second edit box.
- *szEdit = 0;
- *szEdit2 = 0;
- szOkButton = Text_String( TXT_OK );
- szCancelButton = Text_String( TXT_CANCEL );
- szMiddleButton = NULL;
- }
- //***********************************************************************************************
- SimpleEditDlgClass::~SimpleEditDlgClass()
- {
- delete [] szTitle;
- delete [] szPrompt;
- delete [] szPrompt2;
- }
- //***********************************************************************************************
- void SimpleEditDlgClass::SetButtons( const char* szOk, const char* szCancel, const char* szMiddle /*= NULL*/ )
- {
- szOkButton = szOk;
- szCancelButton = szCancel;
- szMiddleButton = szMiddle;
- }
- //***********************************************************************************************
- const char* SimpleEditDlgClass::Show()
- {
- // Shows dialog, returns text of button pressed.
- // Unless SetButtons() is used, value will be TXT_OK or TXT_CANCEL string values.
- bool bEscapeDown = false;
- bool bReturnDown = false;
- /*
- ** Dialog & button dimensions
- */
- int x_margin = 18 * RESFACTOR; // margin width/height
- int y_margin = 10 * RESFACTOR; // margin width/height
- int d_gap_y = 5 * RESFACTOR;
- int d_dialog_w = iDialogWidth;
- int d_dialog_h = szPrompt2 ? ( 29 * RESFACTOR ) + 2 * d_gap_y + 2 * y_margin : ( 19 * RESFACTOR ) + d_gap_y + 2 * y_margin;
- if( szTitle )
- d_dialog_h += 10 * RESFACTOR + 2 * d_gap_y;
- int d_dialog_x = (((320 * RESFACTOR) - d_dialog_w) / 2);
- int d_dialog_y = (((200 * RESFACTOR) - d_dialog_h) / 2);
- int d_dialog_cx = d_dialog_x + (d_dialog_w / 2); // coord of x-center
- /*
- if( szTitle )
- {
- d_title_w = String_Pixel_Width( szTitle );
- d_title_h = 10 * RESFACTOR;
- d_title_x = d_dialog_cx - d_title_w / 2;
- d_title_y = d_dialog_y + d_gap_y;
- }
- */
- int d_prompt_w = String_Pixel_Width( szPrompt );
- int d_prompt_h = 10 * RESFACTOR;
- int d_prompt_x = d_dialog_x + x_margin;
- int d_prompt_y = szTitle ? ( d_dialog_y + 3 * d_gap_y + 10 * RESFACTOR ) : ( d_dialog_y + d_gap_y );
- int d_edit_w = d_dialog_w - d_prompt_w - 2 * x_margin;
- int d_edit_h = 10 * RESFACTOR;
- int d_edit_x = d_dialog_x + d_prompt_w + x_margin;
- int d_edit_y = d_prompt_y;
- int d_prompt2_w = szPrompt2 ? String_Pixel_Width( szPrompt2 ) : 0;
- int d_prompt2_h = 10 * RESFACTOR;
- int d_prompt2_x = d_dialog_x + x_margin;
- int d_prompt2_y = d_prompt_y + d_prompt2_h + d_gap_y;
- int d_edit2_w = d_dialog_w - d_prompt2_w - 2 * x_margin;
- int d_edit2_h = 10 * RESFACTOR;
- int d_edit2_x = d_dialog_x + d_prompt2_w + x_margin;
- int d_edit2_y = d_prompt2_y;
- int d_ok_w, d_ok_h, d_ok_x, d_ok_y, d_cancel_w, d_cancel_h, d_cancel_x, d_cancel_y, d_mid_x, d_mid_y, d_mid_w, d_mid_h;
- if( !szMiddleButton )
- {
- d_ok_w = 40 * RESFACTOR;
- d_ok_h = 9 * RESFACTOR;
- d_ok_x = d_dialog_cx - d_ok_w - 10 * RESFACTOR;
- d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - y_margin;
- d_cancel_w = 40 * RESFACTOR;
- d_cancel_h = 9 * RESFACTOR;
- d_cancel_x = d_dialog_cx + 10 * RESFACTOR;
- d_cancel_y = d_ok_y;
- }
- else
- {
- d_ok_w = 40 * RESFACTOR;
- d_ok_h = 9 * RESFACTOR;
- d_ok_x = d_dialog_cx - d_ok_w - 30 * RESFACTOR;
- d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - y_margin;
- d_mid_w = 40 * RESFACTOR;
- d_mid_h = 9 * RESFACTOR;
- d_mid_x = d_dialog_cx - ( d_mid_w / 2 );
- d_mid_y = d_ok_y;
- d_cancel_w = 40 * RESFACTOR;
- d_cancel_h = 9 * RESFACTOR;
- d_cancel_x = d_dialog_cx + 30 * RESFACTOR;
- d_cancel_y = d_ok_y;
- }
- /*
- ** Button enumerations
- */
- enum {
- BUTTON_OK = 100,
- BUTTON_CANCEL,
- BUTTON_MIDDLE,
- BUTTON_EDIT,
- BUTTON_EDIT2
- };
- /*
- ** Redraw values: in order from "top" to "bottom" layer of the dialog
- */
- typedef enum {
- REDRAW_NONE = 0,
- REDRAW_BUTTONS,
- REDRAW_BACKGROUND,
- REDRAW_ALL = REDRAW_BACKGROUND
- } RedrawType;
- /*
- ** Dialog variables
- */
- const char* szReturn = NULL;
- /*
- ** Buttons
- */
- ControlClass* commands = NULL; // the button list
- TextButtonClass OkBtn( BUTTON_OK, szOkButton, TPF_BUTTON, d_ok_x, d_ok_y, d_ok_w );
- TextButtonClass CancelBtn( BUTTON_CANCEL, szCancelButton, TPF_BUTTON, d_cancel_x, d_cancel_y, d_cancel_w );
- TextButtonClass MiddleBtn( BUTTON_MIDDLE, szMiddleButton, TPF_BUTTON, d_mid_x, d_mid_y, d_mid_w );
- WOLEditClass EditBox( BUTTON_EDIT, szEdit, min( sizeof(szEdit), iEditCharsAccept ), TPF_6PT_GRAD|TPF_NOSHADOW,
- d_edit_x, d_edit_y, d_edit_w, -1, EditClass::ALPHANUMERIC );
- WOLEditClass EditBox2( BUTTON_EDIT2, szEdit2, min( sizeof(szEdit2), iEditCharsAccept2 ), TPF_6PT_GRAD|TPF_NOSHADOW,
- d_edit2_x, d_edit2_y, d_edit2_w, -1, EditClass::ALPHANUMERIC );
- /*
- ** Initialize.
- */
- Set_Logic_Page(SeenBuff);
- /*
- ** Create the button list.
- */
- commands = &OkBtn;
- CancelBtn.Add_Tail(*commands);
- if( szMiddleButton )
- MiddleBtn.Add_Tail(*commands);
- EditBox.Add_Tail(*commands);
- if( szPrompt2 )
- EditBox2.Add_Tail(*commands);
- EditBox.Set_Focus();
- /*
- ** Main Processing Loop.
- */
- Keyboard->Clear();
- bool firsttime = true;
- bool display = true;
- bool process = true;
- while (process) {
- /*
- ** Invoke game callback.
- */
- Call_Back();
- #ifdef WIN32
- /*
- ** If we have just received input focus again after running in the background then
- ** we need to redraw.
- */
- if (AllSurfaces.SurfacesRestored) {
- AllSurfaces.SurfacesRestored=FALSE;
- display = true;
- }
- #endif
- /*
- ** Refresh display if needed.
- */
- if (display) {
- /*
- ** Display the dialog box.
- */
- Hide_Mouse();
- if (display) {
- Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
- if( szTitle )
- Draw_Caption( szTitle, d_dialog_x, d_dialog_y, d_dialog_w );
- }
- /*
- ** Redraw the buttons.
- */
- if (display) {
- Fancy_Text_Print( szPrompt, d_prompt_x, d_prompt_y,
- GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT );
- if( szPrompt2 )
- Fancy_Text_Print( szPrompt2, d_prompt2_x, d_prompt2_y,
- GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT );
- commands->Flag_List_To_Redraw();
- }
- Show_Mouse();
- display = false;
- }
- /*
- ** Get user input.
- */
- KeyNumType input = commands->Input();
- /*
- ** The first time through the processing loop, set the edit
- ** gadget to have the focus. The
- ** focus must be set here since the gadget list has changed
- ** and this change will cause any previous focus setting to be
- ** cleared by the input processing routine.
- */
- if (firsttime ) {
- firsttime = false;
- EditBox.Set_Focus();
- EditBox.Flag_To_Redraw();
- }
- // My hack for triggering escape and return on key up instead of down...
- // The problem that was occurring was that the calling dialog would act on the key up,
- // though this dialog handled the key down. ajw
- if( ( ::GetAsyncKeyState( VK_ESCAPE ) & 0x8000 ) )
- {
- bEscapeDown = true;
- }
- else if( bEscapeDown )
- {
- input = (KeyNumType)( BUTTON_CANCEL | KN_BUTTON );
- bEscapeDown = false;
- }
- if( ( ::GetAsyncKeyState( VK_RETURN ) & 0x8000 ) )
- {
- bReturnDown = true;
- }
- else if( bReturnDown )
- {
- input = (KeyNumType)( BUTTON_OK | KN_BUTTON );
- bReturnDown = false;
- }
- // I really hate to do this, but... ajw
- if( cancel_current_msgbox )
- {
- cancel_current_msgbox = false;
- input = (KeyNumType)( BUTTON_CANCEL | KN_BUTTON );
- }
- if( disable_current_msgbox )
- {
- disable_current_msgbox = false;
- EditBox.Disable();
- // These do not actually draw. I am actually clearing the "draw" flag!
- // Problem is Disable sets them to redraw, and I don't want to, and there is no Flag_To_Redraw( false ).
- EditBox.GadgetClass::Draw_Me( true );
- if( szPrompt2 )
- {
- EditBox2.Disable();
- EditBox2.GadgetClass::Draw_Me( true );
- }
- OkBtn.Disable();
- OkBtn.GadgetClass::Draw_Me( true );
- CancelBtn.Disable();
- CancelBtn.GadgetClass::Draw_Me( true );
- if( szMiddleButton )
- {
- MiddleBtn.Disable();
- MiddleBtn.GadgetClass::Draw_Me( true );
- }
- }
- /*
- ** Process input.
- */
- switch( input )
- {
- // case ( KN_ESC ):
- case ( BUTTON_CANCEL | KN_BUTTON ):
- szReturn = szCancelButton;
- process = false;
- break;
- // case KN_RETURN:
- case ( BUTTON_EDIT | KN_BUTTON ): // (Return pressed while on edit.)
- case ( BUTTON_OK | KN_BUTTON ):
- szReturn = szOkButton;
- process = false;
- break;
- case ( BUTTON_MIDDLE | KN_BUTTON ):
- szReturn = szMiddleButton;
- process = false;
- break;
- default:
- break;
- }
- }
- return szReturn;
- }
- #endif
|