CnC_Remastered_Collection

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

EDIT.CPP (23788B)


      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 /* $Header:   F:\projects\c&c\vcs\code\edit.cpv   2.18   16 Oct 1995 16:48:16   JOE_BOSTIC  $ */
     17 /***********************************************************************************************
     18  ***             C O N F I D E N T I A L  ---  W E S T W O O D   S T U D I O S               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : EDIT.CPP                                                     *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic, Maria del Mar McCready Legg                   *
     26  *                                                                                             *
     27  *                   Start Date : 01/15/95                                                     *
     28  *                                                                                             *
     29  *                  Last Update : June 25, 1995 [JLB]                                          *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   EditClass::Action -- Handles input events.                                                *
     34  *   EditClass::Draw_Background -- Draw the background to the edit gadget.                     *
     35  *   EditClass::Draw_Me -- Draws the edit box and embedded text.                               *
     36  *   EditClass::Draw_Text -- Draws the edit gadget text.                                       *
     37  *   EditClass::EditClass -- Normal constructor for edit class object.                         *
     38  *   EditClass::Handle_Key -- Handles keyboard input to edit gadget.                           *
     39  *   EditClass::Set_Text -- Sets the text to the edit gadget.                                  *
     40  *   EditClass::~EditClass -- Default destructor for the edit gadget.                          *
     41  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     42 
     43 #include	"function.h"
     44 
     45 
     46 /***********************************************************************************************
     47  * EditClass::EditClass -- Normal constructor for edit class object.                           *
     48  *                                                                                             *
     49  *    This is the normal constructor used to create an edit object.                            *
     50  *                                                                                             *
     51  * INPUT:   id    -- The ID number for this edit object. This is the ID number that will be    *
     52  *                   returned by the Input() function when the <RETURN> key is pressed if this *
     53  *                   gadget has the keyboard input focus.                                      *
     54  *                                                                                             *
     55  *          text  -- Referenct to the text buffer that the edit gadget will modify as keyboard *
     56  *                   input is processed. The value that this buffer contains is the default    *
     57  *                   text displayed.                                                           *
     58  *                                                                                             *
     59  *          maxlen-- The maximum size of the text buffer specified. This length INCLUDES the   *
     60  *                   trailing null character so a simple sizeof() function call can be used.   *
     61  *                                                                                             *
     62  *          flags -- These are the text print control flags. It is used to control how the     *
     63  *                   text looks in the edit box. Use the normal TPF_??? flags.                 *
     64  *                                                                                             *
     65  *          x,y   -- The pixel coordinates of the upper left corner of the edit gadget area.   *
     66  *                                                                                             *
     67  *          w,h   -- The pixel dimensions of the edit box. If either of these are no provided, *
     68  *                   or set to -1, then the dimension is determined from the string itself.    *
     69  *                                                                                             *
     70  *          sytle -- This style flag parameter control what kind of characters are allowed in  *
     71  *                   the edit box. The initial string in the text buffer may contain illegal   *
     72  *                   characters, but they are NOT removed regardless of this parameter.        *
     73  *                                                                                             *
     74  * OUTPUT:     none                                                                            *
     75  * WARNINGS:   none                                                                            *
     76  * HISTORY:                                                                                    *
     77  *   01/05/1995 MML : Created.                                                                 *
     78  *   01/21/1995 JLB : Modified.                                                                *
     79  *=============================================================================================*/
     80 EditClass::EditClass(int id, char * text, int max_len, TextPrintType flags, int x, int y, int w, int h, EditStyle style) :
     81 	ControlClass (id, x, y, w, h, LEFTPRESS), String(text)
     82 {
     83 	TextFlags = flags;
     84 	EditFlags = style;
     85 	Color = CC_GREEN;
     86 	Set_Text(text, max_len);
     87 
     88 	if (w == -1 || h == -1) {
     89 		Fancy_Text_Print(TXT_NONE, 0, 0, TBLACK, TBLACK, TextFlags);
     90 
     91 		if (h == -1) {
     92 			Height = FontHeight+2;
     93 		}
     94 		if (w == -1) {
     95 			if (strlen(String) > 0) {
     96 				Width = String_Pixel_Width(String) + 6;
     97 			} else {
     98 				Width = ((Char_Pixel_Width('X')+FontXSpacing) * (MaxLength+1)) + 2;
     99 			}
    100     	}
    101 	}
    102 	IsReadOnly = 0;
    103 }
    104 
    105 
    106 /***********************************************************************************************
    107  * EditClass::~EditClass -- Default destructor for the edit gadget.                            *
    108  *                                                                                             *
    109  *    This default destructor removes the focus setting if it currently has it.                *
    110  *                                                                                             *
    111  * INPUT:   none                                                                               *
    112  *                                                                                             *
    113  * OUTPUT:  none                                                                               *
    114  *                                                                                             *
    115  * WARNINGS:   none                                                                            *
    116  *                                                                                             *
    117  * HISTORY:                                                                                    *
    118  *   01/24/1995 JLB : Created.                                                                 *
    119  *=============================================================================================*/
    120 EditClass::~EditClass(void)
    121 {
    122 	if (Has_Focus()) {
    123 		Clear_Focus();
    124 	}
    125 }
    126 
    127 
    128 /***********************************************************************************************
    129  * EditClass::Set_Text -- Sets the text to the edit gadget.                                    *
    130  *                                                                                             *
    131  *    Use this routine to change the text that this edit gadget refers to.                     *
    132  *                                                                                             *
    133  * INPUT:   text     -- Reference to the character array that this edit gadget will be         *
    134  *                      modifying.                                                             *
    135  *          max_len  -- The maximum size of the buffer that will be modified.                  *
    136  *                                                                                             *
    137  * OUTPUT:  none                                                                               *
    138  * WARNINGS:   none                                                                            *
    139  * HISTORY:                                                                                    *
    140  *   01/21/1995 JLB : Created.                                                                 *
    141  *=============================================================================================*/
    142 void EditClass::Set_Text(char * text, int max_len)
    143 {
    144 	String = text;
    145 	MaxLength = max_len-1;
    146 	Length = strlen(String);
    147 	Flag_To_Redraw();
    148 }
    149 
    150 
    151 /***********************************************************************************************
    152  * EditClass::Draw_Me -- Draws the edit box and embedded text.                                 *
    153  *                                                                                             *
    154  *    This routine will render the edit box. This will show the box outline as well as any     *
    155  *    text it may contain.                                                                     *
    156  *                                                                                             *
    157  * INPUT:   forced   -- Should the edit box be drawn even if it thinks it doesn't have to?     *
    158  *                                                                                             *
    159  * OUTPUT:  Was the edit box drawn?                                                            *
    160  *                                                                                             *
    161  * WARNINGS:   none                                                                            *
    162  *                                                                                             *
    163  * HISTORY:                                                                                    *
    164  *   06/25/1995 JLB : Created.                                                                 *
    165  *=============================================================================================*/
    166 int EditClass::Draw_Me(int forced)
    167 {
    168 	if (ControlClass::Draw_Me(forced)) {
    169 		/*
    170 		**	Hide the mouse.
    171 		*/
    172 		if (LogicPage == &SeenBuff) {
    173 			Conditional_Hide_Mouse(X, Y, X+Width, Y+Height);
    174 		}
    175 
    176 		/*
    177 		**	Draw the body & set text color.
    178 		*/
    179 		Draw_Background();
    180 
    181 		/*
    182 		**	Display the text.
    183 		*/
    184 		Draw_Text(String);
    185 
    186 		/*
    187 		**	Display the mouse.
    188 		*/
    189 		if (LogicPage == &SeenBuff) {
    190 			Conditional_Show_Mouse();
    191 		}
    192 
    193 		return(true);
    194 	}
    195 	return(false);
    196 }
    197 
    198 
    199 /***********************************************************************************************
    200  * EditClass::Action -- Handles input events.                                                  *
    201  *                                                                                             *
    202  *    This routine will handle all mouse and keyboard events directed at this edit box         *
    203  *    gadget. For keyboard events, this will insert the characters into the edit box.          *
    204  *                                                                                             *
    205  * INPUT:   flags -- The event flag that triggered this function call.                         *
    206  *                                                                                             *
    207  *          key   -- Reference to the keyboard/mouse event that triggered this function call.  *
    208  *                                                                                             *
    209  * OUTPUT:  Should the list be processed further?                                              *
    210  *                                                                                             *
    211  * WARNINGS:   none                                                                            *
    212  *                                                                                             *
    213  * HISTORY:                                                                                    *
    214  *   06/25/1995 JLB : Created.                                                                 *
    215  *=============================================================================================*/
    216 int EditClass::Action(unsigned flags, KeyNumType & key)
    217 {
    218 
    219 	/*
    220 	** If this is a read-only edit box, it's a display-only device
    221 	*/
    222 	if (IsReadOnly) {
    223 		return(false);
    224 	}
    225 
    226 	/*
    227 	**	If the left mouse button is pressed over this gadget, then set the focus to
    228 	**	this gadget. The event flag is cleared so that no button ID number is returned.
    229 	*/
    230 	if ((flags & LEFTPRESS)) {
    231 		flags &= ~LEFTPRESS;
    232 		Set_Focus();
    233 		Flag_To_Redraw();		// force to draw cursor
    234 	}
    235 
    236 	/*
    237 	**	Handle keyboard events here. Normally, the key is added to the string, but if the
    238 	**	RETURN key is pressed, then the button ID number is returned from the Input()
    239 	**	function.
    240 	*/
    241 	if ((flags & KEYBOARD) && Has_Focus()) {
    242 
    243 		/*
    244 		**	Process the keyboard character. If indicated, consume this keyboard event
    245 		**	so that the edit gadget ID number is not returned.
    246 		*/
    247 		if (key == KN_ESC) {
    248 
    249 			Clear_Focus();
    250 			flags = 0;
    251 
    252 		} else {
    253 
    254 			KeyASCIIType ascii = (KeyASCIIType)(Keyboard::To_ASCII(key) & 0x00ff);
    255 
    256 			/*
    257 			** Allow numeric keypad presses to map to ascii numbers
    258 			*/
    259 			if ((key & WWKEY_VK_BIT) && ascii >='0' && ascii <= '9'){
    260 				key &= ~WWKEY_VK_BIT;
    261 
    262 				if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){
    263 					if (Handle_Key (ascii) ) {
    264 						flags &= ~KEYBOARD;
    265 						key = KN_NONE;
    266 					}
    267 				}
    268 
    269 			}else{
    270 
    271 				/*
    272 				** Filter out all special keys except return and backspace
    273 				*/
    274 				if ((!(key & WWKEY_VK_BIT) && ascii >= ' ' && ascii <= 127)
    275 					|| key == KN_RETURN || key == KN_BACKSPACE){
    276 
    277 
    278 					if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){
    279 						if (Handle_Key(Keyboard::To_ASCII(key))) {
    280 							flags &= ~KEYBOARD;
    281 							key = KN_NONE;
    282 						}
    283 					}
    284 				}else{
    285 					//if (key & WWKEY_RLS_BIT){
    286 					//	if ( (!(flags & LEFTRELEASE)) && (!(flags & RIGHTRELEASE))){
    287 							flags &= ~KEYBOARD;
    288 							key = KN_NONE;
    289 					//	}
    290 					//}
    291 				}
    292 			}
    293 		}
    294 	}
    295 
    296 	return(ControlClass::Action(flags, key));
    297 }
    298 
    299 
    300 /***********************************************************************************************
    301  * EditClass::Draw_Background -- Draw the background to the edit gadget.                       *
    302  *                                                                                             *
    303  *    This routine will redraw the edit gadget background. The overlaying text is handled by   *
    304  *    a different routine. The mouse is guaranteed to be hidden when this routine is called.   *
    305  *                                                                                             *
    306  * INPUT:   none                                                                               *
    307  *                                                                                             *
    308  * OUTPUT:  none                                                                               *
    309  *                                                                                             *
    310  * WARNINGS:   none                                                                            *
    311  *                                                                                             *
    312  * HISTORY:                                                                                    *
    313  *   01/21/1995 JLB : Created.                                                                 *
    314  *=============================================================================================*/
    315 void EditClass::Draw_Background(void)
    316 {
    317 	Draw_Box (X, Y, Width, Height, BOXSTYLE_GREEN_BOX, true);
    318 }
    319 
    320 
    321 /***********************************************************************************************
    322  * EditClass::Draw_Text -- Draws the edit gadget text.                                         *
    323  *                                                                                             *
    324  *    This routine is called when the edit gadget text needs to be drawn. The background has   *
    325  *    already been drawn by the time this function is called. The mouse is guaranteed to be    *
    326  *    hidden as well.                                                                          *
    327  *                                                                                             *
    328  * INPUT:   text  -- The text to draw in the edit gadget.                                      *
    329  *                                                                                             *
    330  * OUTPUT:  none                                                                               *
    331  *                                                                                             *
    332  * WARNINGS:   none                                                                            *
    333  *                                                                                             *
    334  * HISTORY:                                                                                    *
    335  *   01/21/1995 JLB : Created.                                                                 *
    336  *=============================================================================================*/
    337 void EditClass::Draw_Text(char const * text)
    338 {
    339 	if (FontPtr == GradFont6Ptr) {
    340 		TextPrintType flags;
    341 
    342 		if (Has_Focus()) {
    343 			flags = TPF_BRIGHT_COLOR;
    344 		} else {
    345 			flags = (TextPrintType)0;
    346 		}
    347 
    348 		Conquer_Clip_Text_Print(text, X+1, Y+1, Color, TBLACK, TextFlags | flags, Width-2);
    349 
    350 		if (Has_Focus() && (int)strlen(text) < MaxLength &&
    351 				((int)String_Pixel_Width(text) + (int)String_Pixel_Width ("_") < Width-2) ) {
    352 			Conquer_Clip_Text_Print( "_", X+1+String_Pixel_Width(text), Y+1, Color, TBLACK, TextFlags | flags);
    353 		}
    354 	} else {
    355 		Conquer_Clip_Text_Print(text, X+1, Y+1, Has_Focus() ? BLUE : WHITE, TBLACK, TextFlags, Width-2);
    356 
    357 		if (Has_Focus() && (int)strlen(text) < MaxLength &&
    358 				((int)String_Pixel_Width(text) + (int)String_Pixel_Width ("_") < Width-2) ) {
    359 			Conquer_Clip_Text_Print("_",X+1+String_Pixel_Width(text),Y+1,BLUE,TBLACK, TextFlags);
    360 		}
    361 	}
    362 
    363 }
    364 
    365 
    366 /***********************************************************************************************
    367  * EditClass::Handle_Key -- Handles keyboard input to edit gadget.                             *
    368  *                                                                                             *
    369  *    This is the gruntwork routine that processes keyboard input to the edit gadget. This     *
    370  *    routine will be called when keyboard input has been detected and this gadget has the     *
    371  *    current focus.                                                                           *
    372  *                                                                                             *
    373  * INPUT:   ascii -- The ASCII key code that was fetched from the keyboard buffer.             *
    374  *                                                                                             *
    375  * OUTPUT:  bool; Should this keyboard input NOT cause the gadget ID number to be returned     *
    376  *                from the controlling Input() routine? Typically, the return value would be   *
    377  *                true unless the focus is lost due to the <RETURN> key being pressed.         *
    378  *                                                                                             *
    379  * WARNINGS:   none                                                                            *
    380  * HISTORY:                                                                                    *
    381  *   01/21/1995 JLB : Created.                                                                 *
    382  *=============================================================================================*/
    383 bool EditClass::Handle_Key(KeyASCIIType ascii)
    384 {
    385 	switch (ascii) {
    386 		/*
    387 		**	Handle the special case of a non-keyboard event. It is possible that this
    388 		**	key code might be passed to this routine if this routine has been overridden
    389 		**	and the key event was consumed.
    390 		*/
    391 		case 0:
    392 			break;
    393 
    394 		/*
    395 		**	If the return key is pressed, then remove the focus from this edit
    396 		**	gadget but otherwise let the normal gadget processing proceed. This
    397 		**	causes the gadget ID number to be returned from the Input() function
    398 		**	so that the controlling program will know that the text can be
    399 		**	processed.
    400 		*/
    401 		case KA_RETURN:
    402 			Clear_Focus();
    403 			return(false);
    404 
    405 		/*
    406 		**	When the BACKSPACE key is pressed, remove the last character in the edit string.
    407 		*/
    408 		case KA_BACKSPACE:
    409 			if (Length) {
    410 				Length--;
    411 				String[Length] = '\0';
    412 				Flag_To_Redraw();
    413 			}
    414 			break;
    415 
    416 		/*
    417 		**	If the keyboard event was not a recognized special key, then examine to see
    418 		**	if it can legally be added to the edit string and do so if possible.
    419 		*/
    420 		default:
    421 
    422 			/*
    423 			**	Don't add a character if the length is greater than edit width.
    424 			*/
    425 			if (((int)String_Pixel_Width(String) + (int)Char_Pixel_Width(ascii) ) >= (Width-2)) {
    426 				break;
    427 			}
    428 
    429 			/*
    430 			**	Don't add a character if the length is already at maximum.
    431 			*/
    432 			if (Length >= MaxLength) break;
    433 
    434 			/*
    435 			**	Invisible characters are never added to the string. This is
    436 			**	especially true for spaces at the beginning of the string.
    437 			*/
    438 			if (!isgraph(ascii) && ascii != ' ') break;
    439 			if (ascii == ' ' && Length == 0) break;
    440 
    441 			/*
    442 			**	If this is an upper case only edit gadget, then force the alphabetic
    443 			**	character to upper case.
    444 			*/
    445 			if ((EditFlags & UPPERCASE) && isalpha(ascii)) {
    446 				ascii = (KeyASCIIType)toupper(ascii);
    447 			}
    448 
    449 			if ((!(EditFlags & NUMERIC) || !isdigit(ascii)) &&
    450 				(!(EditFlags & ALPHA) || !isalpha(ascii)) &&
    451 				(!(EditFlags & MISC) || isalnum(ascii)) &&
    452 				ascii != ' ') {
    453 					break;
    454 			}
    455 
    456 			/*
    457 			**	The character passed all legality checks, so add it to the edit string
    458 			**	and flag this gadget to be redrawn. The manual flag to redraw is needed
    459 			**	because the event flag has been cleared. This prevents the gadget's ID
    460 			**	number from being returned just because the gadget has been edited.
    461 			*/
    462 			String[Length++] = ascii;
    463 			String[Length] = '\0';
    464 			Flag_To_Redraw();
    465 			break;
    466 	}
    467 	return(true);
    468 }