CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

SEDITDLG.CPP (10586B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 #ifdef WOLAPI_INTEGRATION
     17 
     18 //	SEditDlg.cpp - "SimpleEditDlgClass": An ok/cancel type dialog with 1 or 2 edit boxes.
     19 //					Mostly a hack for what I need right now - not necessarily very flexible.
     20 //					Still - I can't believe there isn't a set of dialog classes in here already.
     21 //	ajw 07/21/98
     22 
     23 #include "SEditDlg.h"
     24 #include "WOLEdit.h"
     25 
     26 extern bool cancel_current_msgbox;
     27 bool disable_current_msgbox = false;
     28 
     29 //***********************************************************************************************
     30 SimpleEditDlgClass::SimpleEditDlgClass( int iDialogWidth, const char* szTitle, const char* szPrompt, int iEditCharsAccept,
     31 											const char* szPrompt2 /* = NULL */, int iEditCharsAccept2 /* = 0 */ )
     32 	: iDialogWidth( iDialogWidth ), iEditCharsAccept( iEditCharsAccept ), iEditCharsAccept2( iEditCharsAccept2 )
     33 {
     34 	//	Copy strings.
     35 	if( szTitle )
     36 	{
     37 		this->szTitle = new char[ strlen( szTitle ) + 1 ];
     38 		strcpy( this->szTitle, szTitle );
     39 	}
     40 	else
     41 		this->szTitle = NULL;
     42 
     43 	if( szPrompt )
     44 	{
     45 		this->szPrompt = new char[ strlen( szPrompt ) + 1 ];
     46 		strcpy( this->szPrompt, szPrompt );
     47 	}
     48 	else
     49 		this->szPrompt = NULL;		//	I wouldn't try this ... not totally implemented.
     50 
     51 	if( szPrompt2 )
     52 	{
     53 		this->szPrompt2 = new char[ strlen( szPrompt2 ) + 1 ];
     54 		strcpy( this->szPrompt2, szPrompt2 );
     55 	}
     56 	else
     57 		this->szPrompt2 = NULL;		//	This is the flag for whether or not there is a second edit box.
     58 
     59 	*szEdit = 0;
     60 	*szEdit2 = 0;
     61 
     62 	szOkButton = Text_String( TXT_OK );
     63 	szCancelButton = Text_String( TXT_CANCEL );
     64 	szMiddleButton = NULL;
     65 }
     66 
     67 //***********************************************************************************************
     68 SimpleEditDlgClass::~SimpleEditDlgClass()
     69 {
     70 	delete [] szTitle;
     71 	delete [] szPrompt;
     72 	delete [] szPrompt2;
     73 }
     74 
     75 //***********************************************************************************************
     76 void SimpleEditDlgClass::SetButtons( const char* szOk, const char* szCancel, const char* szMiddle /*= NULL*/ )
     77 {
     78 	szOkButton = szOk;
     79 	szCancelButton = szCancel;
     80 	szMiddleButton = szMiddle;
     81 }
     82 
     83 //***********************************************************************************************
     84 const char* SimpleEditDlgClass::Show()
     85 {
     86 	//	Shows dialog, returns text of button pressed.
     87 	//	Unless SetButtons() is used, value will be TXT_OK or TXT_CANCEL string values.
     88 
     89 	bool bEscapeDown = false;
     90 	bool bReturnDown = false;
     91 
     92 	/*
     93 	**	Dialog & button dimensions
     94 	*/
     95 	int x_margin = 18 * RESFACTOR;												// margin width/height
     96 	int y_margin = 10 * RESFACTOR;												// margin width/height
     97 	int d_gap_y = 5 * RESFACTOR;
     98 
     99 	int d_dialog_w = iDialogWidth;
    100 	int d_dialog_h = szPrompt2 ? ( 29 * RESFACTOR ) + 2 * d_gap_y + 2 * y_margin : ( 19 * RESFACTOR ) + d_gap_y + 2 * y_margin;
    101 	if( szTitle )
    102 		d_dialog_h += 10 * RESFACTOR + 2 * d_gap_y;
    103 	int d_dialog_x = (((320 * RESFACTOR) - d_dialog_w) / 2);
    104 	int d_dialog_y = (((200 * RESFACTOR) - d_dialog_h) / 2);
    105 	int d_dialog_cx = d_dialog_x + (d_dialog_w / 2);		// coord of x-center
    106 
    107 /*
    108 	if( szTitle )
    109 	{
    110 		d_title_w = String_Pixel_Width( szTitle );
    111 		d_title_h = 10 * RESFACTOR;
    112 		d_title_x = d_dialog_cx - d_title_w / 2;
    113 		d_title_y = d_dialog_y + d_gap_y;
    114 	}
    115 */
    116 
    117 	int d_prompt_w = String_Pixel_Width( szPrompt );
    118 	int d_prompt_h = 10 * RESFACTOR;
    119 	int d_prompt_x = d_dialog_x + x_margin;
    120 	int d_prompt_y = szTitle ? ( d_dialog_y + 3 * d_gap_y + 10 * RESFACTOR ) : ( d_dialog_y + d_gap_y );
    121 
    122 	int d_edit_w = d_dialog_w - d_prompt_w - 2 * x_margin;
    123 	int d_edit_h = 10 * RESFACTOR;
    124 	int d_edit_x = d_dialog_x + d_prompt_w + x_margin;
    125 	int d_edit_y = d_prompt_y;
    126 
    127 	int d_prompt2_w = szPrompt2 ? String_Pixel_Width( szPrompt2 ) : 0;
    128 	int d_prompt2_h = 10 * RESFACTOR;
    129 	int d_prompt2_x = d_dialog_x + x_margin;
    130 	int d_prompt2_y = d_prompt_y + d_prompt2_h + d_gap_y;
    131 
    132 	int d_edit2_w = d_dialog_w - d_prompt2_w - 2 * x_margin;
    133 	int d_edit2_h = 10 * RESFACTOR;
    134 	int d_edit2_x = d_dialog_x + d_prompt2_w + x_margin;
    135 	int d_edit2_y = d_prompt2_y;
    136 
    137 	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;
    138 
    139 	if( !szMiddleButton )
    140 	{
    141 		d_ok_w = 40 * RESFACTOR;
    142 		d_ok_h = 9 * RESFACTOR;
    143 		d_ok_x = d_dialog_cx - d_ok_w - 10 * RESFACTOR;
    144 		d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - y_margin;
    145 
    146 		d_cancel_w = 40 * RESFACTOR;
    147 		d_cancel_h = 9 * RESFACTOR;
    148 		d_cancel_x = d_dialog_cx + 10 * RESFACTOR;
    149 		d_cancel_y = d_ok_y;
    150 	}
    151 	else
    152 	{
    153 		d_ok_w = 40 * RESFACTOR;
    154 		d_ok_h = 9 * RESFACTOR;
    155 		d_ok_x = d_dialog_cx - d_ok_w - 30 * RESFACTOR;
    156 		d_ok_y = d_dialog_y + d_dialog_h - d_ok_h - y_margin;
    157 
    158 		d_mid_w = 40 * RESFACTOR;
    159 		d_mid_h = 9 * RESFACTOR;
    160 		d_mid_x = d_dialog_cx - ( d_mid_w / 2 );
    161 		d_mid_y = d_ok_y;
    162 
    163 		d_cancel_w = 40 * RESFACTOR;
    164 		d_cancel_h = 9 * RESFACTOR;
    165 		d_cancel_x = d_dialog_cx + 30 * RESFACTOR;
    166 		d_cancel_y = d_ok_y;
    167 	}
    168 
    169 	/*
    170 	**	Button enumerations
    171 	*/
    172 	enum {
    173 		BUTTON_OK = 100,
    174 		BUTTON_CANCEL,
    175 		BUTTON_MIDDLE,
    176 		BUTTON_EDIT,
    177 		BUTTON_EDIT2
    178 	};
    179 
    180 	/*
    181 	**	Redraw values: in order from "top" to "bottom" layer of the dialog
    182 	*/
    183 	typedef enum {
    184 		REDRAW_NONE = 0,
    185 		REDRAW_BUTTONS,
    186 		REDRAW_BACKGROUND,
    187 		REDRAW_ALL = REDRAW_BACKGROUND
    188 	} RedrawType;
    189 
    190 	/*
    191 	**	Dialog variables
    192 	*/
    193 	const char* szReturn = NULL;
    194 
    195 	/*
    196 	**	Buttons
    197 	*/
    198 	ControlClass* commands = NULL;		// the button list
    199 
    200 	TextButtonClass OkBtn( BUTTON_OK, szOkButton, TPF_BUTTON, d_ok_x, d_ok_y, d_ok_w );
    201 	TextButtonClass CancelBtn( BUTTON_CANCEL, szCancelButton, TPF_BUTTON, d_cancel_x, d_cancel_y, d_cancel_w );
    202 	TextButtonClass MiddleBtn( BUTTON_MIDDLE, szMiddleButton, TPF_BUTTON, d_mid_x, d_mid_y, d_mid_w );
    203 
    204 	WOLEditClass EditBox( BUTTON_EDIT, szEdit, min( sizeof(szEdit), iEditCharsAccept ), TPF_6PT_GRAD|TPF_NOSHADOW, 
    205 							d_edit_x, d_edit_y, d_edit_w, -1, EditClass::ALPHANUMERIC );
    206 	WOLEditClass EditBox2( BUTTON_EDIT2, szEdit2, min( sizeof(szEdit2), iEditCharsAccept2 ), TPF_6PT_GRAD|TPF_NOSHADOW, 
    207 							d_edit2_x, d_edit2_y, d_edit2_w, -1, EditClass::ALPHANUMERIC );
    208 
    209 	/*
    210 	**	Initialize.
    211 	*/
    212 	Set_Logic_Page(SeenBuff);
    213 
    214 	/*
    215 	**	Create the button list.
    216 	*/
    217 	commands = &OkBtn;
    218 	CancelBtn.Add_Tail(*commands);
    219 	if( szMiddleButton )
    220 		MiddleBtn.Add_Tail(*commands);
    221 	EditBox.Add_Tail(*commands);
    222 	if( szPrompt2 )
    223 		EditBox2.Add_Tail(*commands);
    224 	EditBox.Set_Focus();
    225 
    226 	/*
    227 	**	Main Processing Loop.
    228 	*/
    229 	Keyboard->Clear();
    230 	bool firsttime = true;
    231 	bool display = true;
    232 	bool process = true;
    233 	while (process) {
    234 
    235 		/*
    236 		**	Invoke game callback.
    237 		*/
    238 		Call_Back();
    239 
    240 		#ifdef WIN32
    241 		/*
    242 		** If we have just received input focus again after running in the background then
    243 		** we need to redraw.
    244 		*/
    245 		if (AllSurfaces.SurfacesRestored) {
    246 			AllSurfaces.SurfacesRestored=FALSE;
    247 			display = true;
    248 		}
    249 		#endif
    250 
    251 		/*
    252 		**	Refresh display if needed.
    253 		*/
    254 		if (display) {
    255 
    256 			/*
    257 			**	Display the dialog box.
    258 			*/
    259 			Hide_Mouse();
    260 			if (display) {
    261 				Dialog_Box(d_dialog_x, d_dialog_y, d_dialog_w, d_dialog_h);
    262 				if( szTitle )
    263 					Draw_Caption( szTitle, d_dialog_x, d_dialog_y, d_dialog_w );
    264 			}
    265 
    266 			/*
    267 			**	Redraw the buttons.
    268 			*/
    269 			if (display) {
    270 				Fancy_Text_Print( szPrompt, d_prompt_x, d_prompt_y,
    271 									GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT );
    272 				if( szPrompt2 )
    273 					Fancy_Text_Print( szPrompt2, d_prompt2_x, d_prompt2_y,
    274 										GadgetClass::Get_Color_Scheme(), TBLACK, TPF_TEXT );
    275 
    276 				commands->Flag_List_To_Redraw();
    277 			}
    278 			Show_Mouse();
    279 			display = false;
    280 		}
    281 
    282 		/*
    283 		**	Get user input.
    284 		*/
    285 		KeyNumType input = commands->Input();
    286 
    287 		/*
    288 		**	The first time through the processing loop, set the edit
    289 		**	gadget to have the focus. The
    290 		**	focus must be set here since the gadget list has changed
    291 		**	and this change will cause any previous focus setting to be
    292 		**	cleared by the input processing routine.
    293 		*/
    294 		if (firsttime ) {
    295 			firsttime = false;
    296 			EditBox.Set_Focus();
    297 			EditBox.Flag_To_Redraw();
    298 		}
    299 
    300 		//	My hack for triggering escape and return on key up instead of down...
    301 		//	The problem that was occurring was that the calling dialog would act on the key up,
    302 		//	though this dialog handled the key down. ajw
    303 		if( ( ::GetAsyncKeyState( VK_ESCAPE ) & 0x8000 ) )
    304 		{
    305 			bEscapeDown = true;
    306 		}
    307 		else if( bEscapeDown )
    308 		{
    309 			input = (KeyNumType)( BUTTON_CANCEL | KN_BUTTON );
    310 			bEscapeDown = false;
    311 		}
    312 		if( ( ::GetAsyncKeyState( VK_RETURN ) & 0x8000 ) )
    313 		{
    314 			bReturnDown = true;
    315 		}
    316 		else if( bReturnDown )
    317 		{
    318 			input = (KeyNumType)( BUTTON_OK | KN_BUTTON );
    319 			bReturnDown = false;
    320 		}
    321 
    322 		//	I really hate to do this, but...      ajw
    323 		if( cancel_current_msgbox )
    324 		{
    325 			cancel_current_msgbox = false;
    326 			input = (KeyNumType)( BUTTON_CANCEL | KN_BUTTON );
    327 		}
    328 
    329 		if( disable_current_msgbox )
    330 		{
    331 			disable_current_msgbox = false;
    332 			EditBox.Disable();
    333 			//	These do not actually draw. I am actually clearing the "draw" flag!
    334 			//	Problem is Disable sets them to redraw, and I don't want to, and there is no Flag_To_Redraw( false ).
    335 			EditBox.GadgetClass::Draw_Me( true );
    336 			if( szPrompt2 )
    337 			{
    338 				EditBox2.Disable();
    339 				EditBox2.GadgetClass::Draw_Me( true );
    340 			}
    341 			OkBtn.Disable();
    342 			OkBtn.GadgetClass::Draw_Me( true );
    343 			CancelBtn.Disable();
    344 			CancelBtn.GadgetClass::Draw_Me( true );
    345 			if( szMiddleButton )
    346 			{
    347 				MiddleBtn.Disable();
    348 				MiddleBtn.GadgetClass::Draw_Me( true );
    349 			}
    350 		}
    351 
    352 		/*
    353 		**	Process input.
    354 		*/
    355 		switch( input )
    356 		{
    357 //		case ( KN_ESC ):
    358 		case ( BUTTON_CANCEL | KN_BUTTON ):
    359 			szReturn = szCancelButton;
    360 			process = false;
    361 			break;
    362 
    363 //		case KN_RETURN:
    364 		case ( BUTTON_EDIT | KN_BUTTON ):			//	(Return pressed while on edit.)
    365 		case ( BUTTON_OK | KN_BUTTON ):
    366 			szReturn = szOkButton;
    367 			process = false;
    368 			break;
    369 
    370 		case ( BUTTON_MIDDLE | KN_BUTTON ):
    371 			szReturn = szMiddleButton;
    372 			process = false;
    373 			break;
    374 
    375 		default:
    376 			break;
    377 		}
    378 	}
    379 
    380 	return szReturn;
    381 }
    382 
    383 #endif