CnC_Remastered_Collection

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

GADGET.CPP (43781B)


      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\gadget.cpv   2.18   16 Oct 1995 16:49:40   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 : GADGET.CPP                                                   *
     24  *                                                                                             *
     25  *                   Programmer : Maria del Mar McCready Legg                                  *
     26  *                                Joe L. Bostic                                                *
     27  *                                                                                             *
     28  *                   Start Date : 01/03/95                                                     *
     29  *                                                                                             *
     30  *                  Last Update : July 8, 1995 [JLB]                                           *
     31  *                                                                                             *
     32  *---------------------------------------------------------------------------------------------*
     33  * Functions:                                                                                  *
     34  *   GadgetClass::Action -- Base action for gadget.                                            *
     35  *   GadgetClass::Clear_Focus -- Clears the focus if this gadget has it.                       *
     36  *   GadgetClass::Delete_List -- Deletes all gadget objects in list.                           *
     37  *   GadgetClass::Disable -- Disables the gaget from input processing.                         *
     38  *   GadgetClass::Draw_All -- Forces all gadgets in list to be redrawn.                        *
     39  *   GadgetClass::Draw_Me -- Gadget redraw action (flag control).                              *
     40  *   GadgetClass::Enable -- Enables the gadget.                                                *
     41  *   GadgetClass::Extract_Gadget -- Sweeps through the gadget chain to find gadget specified.  *
     42  *   GadgetClass::Flag_To_Redraw -- Flags this gadget to be redrawn.                           *
     43  *   GadgetClass::GadgetClass -- Constructor for gadget object.                                *
     44  *   GadgetClass::GadgetClass -- Default constructor for a gadget class object.                *
     45  *   GadgetClass::Get_Next -- Returns a pointer to the next gadget in the chain.               *
     46  *   GadgetClass::Get_Prev -- Fetches a pointer to the previous gadget.                        *
     47  *   GadgetClass::Has_Focus -- Checks if this object currently has the keyboard focus.         *
     48  *   GadgetClass::Remove -- Removes the specified gagdet from the list.                        *
     49  *   GadgetClass::Set_Focus -- Sets focus to this gadget.                                      *
     50  *   GadgetClass::Sticky_Process -- Handles the sticky flag processing.                        *
     51  *   GadgetClass::~GadgetClass -- Destructor for gadget object.                                *
     52  *   GadgetClass::Is_List_To_Redraw -- tells if any gadget in the list needs redrawing         *
     53  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     54 
     55 #include "function.h"
     56 #include <filepcx.h>
     57 #include <io.h>
     58 
     59 /*
     60 **	This records the current gadget the the gadget system is "stuck on". Such a
     61 **	gadget will be processed to the exclusion of all others until the mouse button
     62 **	is no longer pressed.
     63 */
     64 GadgetClass * GadgetClass::StuckOn = 0;
     65 
     66 /*
     67 **	This is a copy of a pointer to the last list used by the gadget input system.
     68 **	If a change of list is detected, then all gadgets are forced to be redrawn.
     69 */
     70 GadgetClass * GadgetClass::LastList = 0;
     71 
     72 
     73 /*
     74 **	This points to the gadget that is intercepting all keyboard events.
     75 */
     76 GadgetClass * GadgetClass::Focused = 0;
     77 
     78 
     79 /***********************************************************************************************
     80  * GadgetClass::GadgetClass -- Constructor for gadget object.                                  *
     81  *                                                                                             *
     82  *    This is the normal constructor for gadget objects. A gadget object is only concerned     *
     83  *    with the region on the screen to considered "its own" as well as the flags that tell     *
     84  *    what mouse action should be recognized when the mouse is over this screen area.          *
     85  *                                                                                             *
     86  * INPUT:   x,y   -- Coordinates (in pixels) of the upper left hand corner of the region that  *
     87  *                   will be "owned" by this gadget.                                           *
     88  *                                                                                             *
     89  *          w,h   -- Width and height (in pixels) of this gadget's region.                     *
     90  *                                                                                             *
     91  *          flags -- The flags (mouse conditions) that will cause this gadget's action         *
     92  *                   function to be called.                                                    *
     93  *                                                                                             *
     94  * OUTPUT:  none                                                                               *
     95  *                                                                                             *
     96  * WARNINGS:   none                                                                            *
     97  *                                                                                             *
     98  * HISTORY:                                                                                    *
     99  *   01/03/1995 MML : Created.                                                                 *
    100  *=============================================================================================*/
    101 GadgetClass::GadgetClass(int x, int y, int w, int h, unsigned flags, int sticky)
    102 {
    103 	X = x;
    104 	Y = y;
    105 	Width = w;
    106 	Height = h;
    107 	Flags = flags;
    108 	IsToRepaint = false;
    109 	IsSticky = sticky;
    110 	IsDisabled = false;
    111 
    112 	if (IsSticky) {
    113 		Flags |= LEFTPRESS|LEFTRELEASE;
    114 	}
    115 }
    116 
    117 
    118 /***********************************************************************************************
    119  * GadgetClass::~GadgetClass -- Destructor for gadget object.                                  *
    120  *                                                                                             *
    121  *    This is the destructor for the gadget object. It will clear the focus from this gadget   *
    122  *    if this gadget currently has the focus.                                                  *
    123  *                                                                                             *
    124  * INPUT:   none                                                                               *
    125  *                                                                                             *
    126  * OUTPUT:  none                                                                               *
    127  *                                                                                             *
    128  * WARNINGS:   none                                                                            *
    129  *                                                                                             *
    130  * HISTORY:                                                                                    *
    131  *   07/08/1995 JLB : Created.                                                                 *
    132  *=============================================================================================*/
    133 GadgetClass::~GadgetClass(void)
    134 {
    135 	if (Has_Focus()) {
    136 		Clear_Focus();
    137 	}
    138 }
    139 
    140 
    141 /***************************************************************************
    142  * GADGETCLASS::CLICKEDON -- If a mouse click is detected within gadget's  *
    143  *      area and the appropriate flag is set, then call Action().          *
    144  *                                                                         *
    145  * INPUT:      int key, int mousex, int mousey                             *
    146  *                                                                         *
    147  * OUTPUT:     true or false                                               *
    148  *                                                                         *
    149  * WARNINGS:   none.                                                       *
    150  *                                                                         *
    151  * HISTORY:    01/03/1995 MML : Created.                                   *
    152  *=========================================================================*/
    153 int GadgetClass::Clicked_On(KeyNumType & key, unsigned flags, int mousex, int mousey)
    154 {
    155 	/*
    156 	**	Set flags to match only those events that occur AND are being looked for. If
    157 	**	the result is NULL, then we know that this button should be ignored.
    158 	*/
    159 	flags &= Flags;
    160 
    161 	/*
    162 	**	If keyboard input should be processed by this "gadget" and keyboard input is
    163 	**	detected, then always call the action function. It is up to the action function
    164 	**	in this case to either ignore the keyboard input or not.
    165 	**
    166 	**	For mouse actions, check to see if the mouse is in the region of the button
    167 	**	before calling the associated action function. This is the typical action for
    168 	**	buttons.
    169 	*/
    170 	if (this == StuckOn ||
    171 		(flags & KEYBOARD) ||
    172 		(flags && (mousex - X) < Width  && (mousey - Y) < Height)) {
    173 
    174 		return(Action(flags, key));
    175 	}
    176 	return(false);
    177 }
    178 
    179 
    180 /***********************************************************************************************
    181  * GadgetClass::Enable -- Enables the gadget.                                                  *
    182  *                                                                                             *
    183  *    This function enables the gadget. An enabled gadget will be processed for input          *
    184  *    purposes.                                                                                *
    185  *                                                                                             *
    186  * INPUT:   none                                                                               *
    187  *                                                                                             *
    188  * OUTPUT:  none                                                                               *
    189  *                                                                                             *
    190  * WARNINGS:   none                                                                            *
    191  *                                                                                             *
    192  * HISTORY:                                                                                    *
    193  *   01/15/1995 JLB : Created.                                                                 *
    194  *=============================================================================================*/
    195 void GadgetClass::Enable(void)
    196 {
    197 	IsDisabled = false;
    198 	IsToRepaint = true;
    199 	Clear_Focus();
    200 }
    201 
    202 
    203 /***********************************************************************************************
    204  * GadgetClass::Disable -- Disables the gaget from input processing.                           *
    205  *                                                                                             *
    206  *    This routine will disable the gadget. A disabled gadget might be rendered, but is        *
    207  *    ignored for input processing.                                                            *
    208  *                                                                                             *
    209  * INPUT:   none                                                                               *
    210  *                                                                                             *
    211  * OUTPUT:  none                                                                               *
    212  *                                                                                             *
    213  * WARNINGS:   none                                                                            *
    214  *                                                                                             *
    215  * HISTORY:                                                                                    *
    216  *   01/15/1995 JLB : Created.                                                                 *
    217  *=============================================================================================*/
    218 void GadgetClass::Disable(void)
    219 {
    220 	IsDisabled = true;
    221 	IsToRepaint = true;
    222 	Clear_Focus();
    223 }
    224 
    225 
    226 /***********************************************************************************************
    227  * GadgetClass::Remove -- Removes the specified gagdet from the list.                          *
    228  *                                                                                             *
    229  *    Use this routine if an individual gadget needs to be removed from the list of gadgets.   *
    230  *                                                                                             *
    231  * INPUT:   none                                                                               *
    232  *                                                                                             *
    233  * OUTPUT:  bool; Was the specified gadget found and removed? A false indicates that the       *
    234  *                gadget wasn't in the list.                                                   *
    235  *                                                                                             *
    236  * WARNINGS:   none                                                                            *
    237  *                                                                                             *
    238  * HISTORY:                                                                                    *
    239  *   01/15/1995 JLB : Created.                                                                 *
    240  *=============================================================================================*/
    241 GadgetClass * GadgetClass::Remove(void)
    242 {
    243 	Clear_Focus();
    244 	return(GadgetClass *)LinkClass::Remove();
    245 }
    246 
    247 
    248 /***********************************************************************************************
    249  * GadgetClass::Get_Next -- Returns a pointer to the next gadget in the chain.                 *
    250  *                                                                                             *
    251  *    This returns with the next gadget's pointer. It is identical to the base Get_Next()      *
    252  *    function, but returns a pointer to a GadgetClass object.                                 *
    253  *                                                                                             *
    254  * INPUT:   none                                                                               *
    255  *                                                                                             *
    256  * OUTPUT:  Returns with a pointer to the next gadget in the list.                             *
    257  *                                                                                             *
    258  * WARNINGS:   none                                                                            *
    259  *                                                                                             *
    260  * HISTORY:                                                                                    *
    261  *   01/15/1995 JLB : Created.                                                                 *
    262  *=============================================================================================*/
    263 GadgetClass * GadgetClass::Get_Next(void) const
    264 {
    265 	return(GadgetClass*)LinkClass::Get_Next();
    266 }
    267 
    268 
    269 /***********************************************************************************************
    270  * GadgetClass::Get_Prev -- Fetches a pointer to the previous gadget.                          *
    271  *                                                                                             *
    272  *    This routine will return the previous gadget in the list. It is identical to the base    *
    273  *    function Get_Prev, but returns a pointer to a GadgetClass object.                        *
    274  *                                                                                             *
    275  * INPUT:   none                                                                               *
    276  *                                                                                             *
    277  * OUTPUT:  Returns with a pointer to the previous gadget in the list.                         *
    278  *                                                                                             *
    279  * WARNINGS:   none                                                                            *
    280  *                                                                                             *
    281  * HISTORY:                                                                                    *
    282  *   01/15/1995 JLB : Created.                                                                 *
    283  *=============================================================================================*/
    284 GadgetClass * GadgetClass::Get_Prev(void) const
    285 {
    286 	return(GadgetClass*)LinkClass::Get_Prev();
    287 }
    288 
    289 
    290 /***********************************************************************************************
    291  * GadgetClass::Delete_List -- Deletes all gadget objects in list.                             *
    292  *                                                                                             *
    293  *    This function will delete all gadgets in the list. It is the counterpart to the          *
    294  *    Create_One_Of functions.                                                                 *
    295  *                                                                                             *
    296  * INPUT:   none                                                                               *
    297  *                                                                                             *
    298  * OUTPUT:  none                                                                               *
    299  *                                                                                             *
    300  * WARNINGS:   Any references to these gadget become invalidated by this routine.              *
    301  *                                                                                             *
    302  * HISTORY:                                                                                    *
    303  *   01/15/1995 JLB : Created.                                                                 *
    304  *=============================================================================================*/
    305 void GadgetClass::Delete_List(void)
    306 {
    307 	GadgetClass * g = this;
    308 
    309 	/*
    310 	**	Move to head of the list.
    311 	*/
    312 	while (g->Get_Prev()) {
    313 		g = g->Get_Prev();
    314 	}
    315 
    316 	/*
    317 	**	First delete all the gadgets following the first one. The reason the first one
    318 	**	is kept around is that sometimes deleting one gadget will result in related gadgets
    319 	**	in the same list also being deleted. The first gadget will always contain the
    320 	**	correct gadget pointer.
    321 	*/
    322 	while (g) {
    323 		g->Clear_Focus();
    324 
    325 		GadgetClass * temp = g;
    326 		g = g->Get_Next();
    327 		delete temp;
    328 	}
    329 }
    330 
    331 
    332 /***********************************************************************************************
    333  * GadgetClass::Action -- Base action for gadget.                                              *
    334  *                                                                                             *
    335  *    This handles the base level action that a gadget performs when a qualifying input event  *
    336  *    is detected. This sets the redraw flag and returns true (to stop further processing).    *
    337  *    If no qualifying input event was detected, but this routine was called anyway, then      *
    338  *    don't perform any action. The call to this routine, in that case, must have been forced  *
    339  *    for some other reason.                                                                   *
    340  *                                                                                             *
    341  * INPUT:   flag  -- The input event bits that qualify for this gadget. A NULL indicates that  *
    342  *                   no qualifying event occured.                                              *
    343  *                                                                                             *
    344  * OUTPUT:  bool; Should further gadget list processing be aborted?                            *
    345  *                                                                                             *
    346  * WARNINGS:   none                                                                            *
    347  *                                                                                             *
    348  * HISTORY:                                                                                    *
    349  *   01/15/1995 JLB : Created.                                                                 *
    350  *=============================================================================================*/
    351 int GadgetClass::Action(unsigned flags, KeyNumType &)
    352 {
    353 	/*
    354 	**	If any of the event flags are active, then this indicates that something probably
    355 	**	has changed the gadget. Flag the gadget to be redrawn. Also, make sure that
    356 	**	any sticky flags are cleared up.
    357 	*/
    358 	if (flags) {
    359 		IsToRepaint = true;
    360 		Sticky_Process(flags);
    361 		return(true);
    362 	}
    363 	return(false);
    364 }
    365 
    366 
    367 /***********************************************************************************************
    368  * GadgetClass::Draw_Me -- Gadget redraw action (flag control).                                *
    369  *                                                                                             *
    370  *    At this level, there is no actual rendering taking place with the call to Draw_Me, but   *
    371  *    the IsToRepaint flag must be cleared. Derived objects will call this routine and if it   *
    372  *    returns true, they will perform their custom rendering.                                  *
    373  *                                                                                             *
    374  * INPUT:   forced   -- Is this redraw forced by outside circumstances?                        *
    375  *                                                                                             *
    376  * OUTPUT:  bool; Should the gadget imagery be redrawn?                                        *
    377  *                                                                                             *
    378  * WARNINGS:   none                                                                            *
    379  *                                                                                             *
    380  * HISTORY:                                                                                    *
    381  *   01/14/1995 JLB : Created.                                                                 *
    382  *=============================================================================================*/
    383 int GadgetClass::Draw_Me(int forced)
    384 {
    385 	if (forced || IsToRepaint) {
    386 		IsToRepaint = false;
    387 		return(true);
    388 	}
    389 	return(false);
    390 }
    391 
    392 
    393 /***********************************************************************************************
    394  * GadgetClass::Draw_All -- Forces all gadgets in list to be redrawn.                          *
    395  *                                                                                             *
    396  *    Use this function to cause all gadget in the list to be redrawn regardless of the state  *
    397  *    of the IsToRepaint flag.                                                                 *
    398  *                                                                                             *
    399  * INPUT:   none                                                                               *
    400  *                                                                                             *
    401  * OUTPUT:  none                                                                               *
    402  *                                                                                             *
    403  * WARNINGS:   none                                                                            *
    404  *                                                                                             *
    405  * HISTORY:                                                                                    *
    406  *   01/03/1995 MML : Created.                                                                 *
    407  *=============================================================================================*/
    408 void GadgetClass::Draw_All(bool forced)
    409 {
    410 	GadgetClass *gadget = this;
    411 
    412 	while (gadget != NULL) {
    413 		gadget->Draw_Me(forced);
    414 		gadget = gadget->Get_Next();
    415 	}
    416 }
    417 
    418 
    419 /***************************************************************************
    420  * GADGETCLASS::PROCESSLIST -- Check list for a mouse click within a gadget*
    421  *                                                                         *
    422  * INPUT:      none.                                                       *
    423  *                                                                         *
    424  * OUTPUT:     key pressed.                                                *
    425  *                                                                         *
    426  * WARNINGS:   none.                                                       *
    427  *                                                                         *
    428  * HISTORY:    01/03/1995 MML : Created.                                   *
    429  *=========================================================================*/
    430 KeyNumType GadgetClass::Input(void)
    431 {
    432 	int mousex, mousey;
    433 	KeyNumType key;
    434 	unsigned flags;
    435 	int forced = false;
    436 
    437 	/*
    438 	**	Record this list so that a forced redraw only occurs the FIRST time the
    439 	**	gadget list is passed to this routine.
    440 	*/
    441 	if (LastList != this) {
    442 		LastList = this;
    443 		forced = true;
    444 		StuckOn = NULL;
    445 		Focused = NULL;
    446 	}
    447 
    448 	/*
    449 	**	Fetch any pending keyboard input.
    450 	*/
    451 	key = Keyboard::Check();
    452 	if (key) {
    453 		key = Keyboard::Get();
    454 	}
    455 
    456 #ifdef SCENARIO_EDITOR
    457 
    458 	if ( key == KN_K ){
    459 		/*
    460 		** time to create a screen shot using the PCX code (if it works)
    461 		*/
    462 		GraphicBufferClass temp_page(	SeenBuff.Get_Width(),
    463 												SeenBuff.Get_Height(),
    464 												NULL,
    465 												SeenBuff.Get_Width() * SeenBuff.Get_Height());
    466 		char filename[30];
    467 
    468 		SeenBuff.Blit(temp_page);
    469 		for (int lp = 0; lp < 99; lp ++) {
    470 			if (lp < 10) {
    471 				sprintf(filename, "scrsht0%d.pcx", lp);
    472 			} else {
    473 				sprintf(filename, "scrsht%d.pcx", lp);
    474 			}
    475 			if (access(filename, F_OK) == -1)
    476 				break;
    477 		}
    478 
    479 		Write_PCX_File(filename, temp_page, (unsigned char *)CurrentPalette);
    480 		//Map.Place_Random_Crate();
    481 	}
    482 
    483 #endif	//SCENARIO_EDITOR
    484 
    485 	/*
    486 	**	For mouse button clicks, the mouse position is actually held in the MouseQ...
    487 	**	globals rather than their normal Mouse... globals. This is because we need to
    488 	**	know the position of the mouse at the exact instant when the click occured
    489 	**	rather the the mouse position at the time we get around to this function.
    490 	*/
    491 	if (((key&0x10FF) == KN_LMOUSE) || ((key&0x10FF) == KN_RMOUSE)) {
    492 	   mousex = _Kbd->MouseQX;
    493 	   mousey = _Kbd->MouseQY;
    494 	} else {
    495 	   mousex = Get_Mouse_X();
    496 	   mousey = Get_Mouse_Y();
    497 	}
    498 
    499 	/*
    500 	**	Set the mouse button state flags. These will be passed to the individual
    501 	**	buttons so that they can determine what action to perform (if any).
    502 	*/
    503 	flags = 0;
    504 	if (key) {
    505 		if (key == KN_LMOUSE) {
    506 			flags |= LEFTPRESS;
    507 		}
    508 		if (key == KN_RMOUSE) {
    509 			flags |= RIGHTPRESS;
    510 		}
    511 		if (key == (KN_LMOUSE | KN_RLSE_BIT)) {
    512 			flags |= LEFTRELEASE;
    513 		}
    514 		if (key == (KN_RMOUSE | KN_RLSE_BIT)) {
    515 			flags |= RIGHTRELEASE;
    516 		}
    517 	}
    518 
    519 	/*
    520 	**	If the mouse wasn't responsible for this key code, then it must be from
    521 	**	the keyboard. Flag this fact.
    522 	*/
    523 	if (key && !flags) {
    524 		flags |= KEYBOARD;
    525 	}
    526 
    527 	/*
    528 	**	Mouse button up or down action is ignored if there is a keyboard event. This
    529 	**	allows keyboard events to fall through normally even if the mouse is over a
    530 	**	gadget that is flagged for LEFTUP or RIGHTUP.
    531 	*/
    532 	if (!key) {
    533 
    534 		/*
    535 		**	Check for the mouse being held down. We can't use the normal input system
    536 		**	for this, so we must examine the actual current state of the mouse
    537 		**	buttons. As a side note, if we determine that the mouse button isn't being
    538 		**	held down, then we automatically know that it must be up -- set the flag
    539 		**	accordingly.
    540 		*/
    541 		if (Keyboard::Down(KN_LMOUSE)) {
    542 			flags |= LEFTHELD;
    543 		} else {
    544 			flags |= LEFTUP;
    545 		}
    546 		if (Keyboard::Down(KN_RMOUSE)) {
    547 			flags |= RIGHTHELD;
    548 		} else {
    549 			flags |= RIGHTUP;
    550 		}
    551 	}
    552 
    553 	/*
    554 	**	If "sticky" processing is active, then only process the stuck gadget.
    555 	*/
    556 	if (StuckOn) {
    557 		StuckOn->Draw_Me(false);
    558 		StuckOn->Clicked_On(key, flags, mousex, mousey);
    559 		if (StuckOn) {
    560 			StuckOn->Draw_Me(false);
    561 		}
    562 	} else {
    563 
    564 		/*
    565 		**	If there is a gadget that has the keyboard focus, then route all keyboard
    566 		**	events to it.
    567 		*/
    568 		if (Focused && (flags & KEYBOARD)) {
    569 			Focused->Draw_Me(false);
    570 			Focused->Clicked_On(key, flags, mousex, mousey);
    571 			if (Focused) {
    572 				Focused->Draw_Me(false);
    573 			}
    574 		} else {
    575 
    576 			/*
    577 			**	Sweep through all the buttons in the chain and pass the current button state
    578 			**	and keyboard input data to them. These routines will detect whether they should
    579 			**	perform some action and return a flag to this effect. They also have the option
    580 			**	of changing the key value so that an appropriate return value is use for this
    581 			**	processing routine.
    582 			*/
    583 			GadgetClass *next_button = this;
    584 			while (next_button != NULL) {
    585 
    586 				/*
    587 				**	Maybe redraw the button if it needs to or is being forced to redraw.
    588 				*/
    589 				next_button->Draw_Me(forced);
    590 
    591 				if (!next_button->IsDisabled) {
    592 
    593 					/*
    594 					**	Process this button. If the button was recognized and action was
    595 					**	performed, then bail from further processing (speed reasons?).
    596 					*/
    597 					if (next_button->Clicked_On(key, flags, mousex, mousey)) {
    598 
    599 						/*
    600 						**	Some buttons will require repainting when they perform some action.
    601 						**	Do so at this time.
    602 						*/
    603 						next_button->Draw_Me(false);
    604 						break;
    605 					}
    606 				}
    607 
    608 				next_button = next_button->Get_Next();
    609 			}
    610 		}
    611 	}
    612 	return(key);
    613 }
    614 
    615 
    616 /***********************************************************************************************
    617  * GadgetClass::Extract_Gadget -- Sweeps through the gadget chain to find gadget specified.    *
    618  *                                                                                             *
    619  *    This examines the gadget list looking for on that has the same ID as specified. If that  *
    620  *    gadget was found, then a pointer to it is returned. Since only ControlClass gadgets      *
    621  *    or ones derived from it can have an ID value, we know that the returned pointer is at    *
    622  *    least of the ControlClass type.                                                          *
    623  *                                                                                             *
    624  * INPUT:   id -- The ID number to scan for. Zero is not a legal ID number and if passed in,   *
    625  *                a NULL will always be returned.                                              *
    626  *                                                                                             *
    627  * OUTPUT:  Returns with a pointer to the ControlClass gadget that has the matching ID number. *
    628  *          If no matching gadget was found, then NULL is returned.                            *
    629  *                                                                                             *
    630  * WARNINGS:   If there happens to be more than one gadget with a matching ID, this routine    *
    631  *             will return a pointer to the first one only.                                    *
    632  *                                                                                             *
    633  * HISTORY:                                                                                    *
    634  *   01/16/1995 JLB : Created.                                                                 *
    635  *=============================================================================================*/
    636 ControlClass * GadgetClass::Extract_Gadget(unsigned id)
    637 {
    638 	GadgetClass * g = this;
    639 
    640 	if (id) {
    641 		while (g) {
    642 			if (g->Get_ID() == id) {
    643 				return((ControlClass *)g);
    644 			}
    645 			g = g->Get_Next();
    646 		}
    647 	}
    648 	return(0);
    649 }
    650 
    651 
    652 /***********************************************************************************************
    653  * GadgetClass::Flag_To_Redraw -- Flags this gadget to be redrawn.                             *
    654  *                                                                                             *
    655  *    Use this routine to flag the gadget to be redrawn. A gadget so flagged will have its     *
    656  *    Draw_Me function called at the next available opportunity. Usually, this is the next     *
    657  *    time the Input() function is called.                                                     *
    658  *                                                                                             *
    659  * INPUT:   none                                                                               *
    660  *                                                                                             *
    661  * OUTPUT:  none                                                                               *
    662  *                                                                                             *
    663  * WARNINGS:   none                                                                            *
    664  *                                                                                             *
    665  * HISTORY:                                                                                    *
    666  *   01/16/1995 JLB : Created.                                                                 *
    667  *=============================================================================================*/
    668 void GadgetClass::Flag_To_Redraw(void)
    669 {
    670 	IsToRepaint = true;
    671 }
    672 
    673 
    674 /***********************************************************************************************
    675  * GadgetClass::Sticky_Process -- Handles the sticky flag processing.                          *
    676  *                                                                                             *
    677  *    This function examines the event flags and handles any "sticky" processing required.     *
    678  *    Sticky processing is when the button is flagged with the "IsSticky" bit and it will      *
    679  *    be processed to the exclusion of all other gadgets while the mouse button is held        *
    680  *    down.                                                                                    *
    681  *                                                                                             *
    682  * INPUT:   flags -- The event flags that triggered the call to this routine.                  *
    683  *                                                                                             *
    684  * OUTPUT:  none                                                                               *
    685  *                                                                                             *
    686  * WARNINGS:   none                                                                            *
    687  *                                                                                             *
    688  * HISTORY:                                                                                    *
    689  *   01/16/1995 JLB : Created.                                                                 *
    690  *=============================================================================================*/
    691 void GadgetClass::Sticky_Process(unsigned flags)
    692 {
    693 	if (IsSticky && (flags & LEFTPRESS)) {
    694 		StuckOn = this;
    695 	}
    696 	if (StuckOn == this && (flags & LEFTRELEASE)) {
    697 		StuckOn = 0;
    698 	}
    699 }
    700 
    701 
    702 /***********************************************************************************************
    703  * GadgetClass::Set_Focus -- Sets focus to this gadget.                                        *
    704  *                                                                                             *
    705  *    This will set the focus to this gadget regardless of any current focus setting. If there *
    706  *    is another gadget that has focus, it will have its focus cleared before this gadget will *
    707  *    get the focus. A focused gadget is one that has all keyboard input routed to it.         *
    708  *                                                                                             *
    709  * INPUT:   none                                                                               *
    710  *                                                                                             *
    711  * OUTPUT:  none                                                                               *
    712  *                                                                                             *
    713  * WARNINGS:   none                                                                            *
    714  *                                                                                             *
    715  * HISTORY:                                                                                    *
    716  *   01/25/1995 JLB : Created.                                                                 *
    717  *=============================================================================================*/
    718 void GadgetClass::Set_Focus(void)
    719 {
    720 	if (Focused) {
    721 		Focused->Flag_To_Redraw();
    722 		Focused->Clear_Focus();
    723 	}
    724 	Flags |= KEYBOARD;
    725 	Focused = this;
    726 }
    727 
    728 
    729 /***********************************************************************************************
    730  * GadgetClass::Clear_Focus -- Clears the focus if this gadget has it.                         *
    731  *                                                                                             *
    732  *    Use this function to clear the focus for the gadget. If the gadget doesn't currently     *
    733  *    have focus, then this routine will do nothing. For added functionality, overload this    *
    734  *    virtual function so that gadget specific actions may be take when focus is lost.         *
    735  *                                                                                             *
    736  * INPUT:   none                                                                               *
    737  *                                                                                             *
    738  * OUTPUT:  none                                                                               *
    739  *                                                                                             *
    740  * WARNINGS:   none                                                                            *
    741  *                                                                                             *
    742  * HISTORY:                                                                                    *
    743  *   01/25/1995 JLB : Created.                                                                 *
    744  *=============================================================================================*/
    745 void GadgetClass::Clear_Focus(void)
    746 {
    747 	if (Focused == this) {
    748 		Flags &= ~KEYBOARD;
    749 		Focused = 0;
    750 	}
    751 }
    752 
    753 
    754 /***********************************************************************************************
    755  * GadgetClass::Has_Focus -- Checks if this object currently has the keyboard focus.           *
    756  *                                                                                             *
    757  *    If this object has the keyboard focus, then this routine will return true. When the      *
    758  *    gadget has keyboard focus, all keyboard events get routed to the gadget.                 *
    759  *                                                                                             *
    760  * INPUT:   none                                                                               *
    761  *                                                                                             *
    762  * OUTPUT:  bool; Does this gadget have the keyboard focus?                                    *
    763  *                                                                                             *
    764  * WARNINGS:   none                                                                            *
    765  *                                                                                             *
    766  * HISTORY:                                                                                    *
    767  *   01/21/1995 JLB : Created.                                                                 *
    768  *=============================================================================================*/
    769 bool GadgetClass::Has_Focus(void)
    770 {
    771 	return(this == Focused);
    772 }
    773 
    774 /***********************************************************************************************
    775  * GadgetClass::Is_List_To_Redraw -- tells if any gadget in the list needs redrawing           *
    776  *                                                                                             *
    777  * This function is mostly for supporting HidPage drawing.  If it returns true, it means       *
    778  * the application needs to re-blit the HidPage forward, after calling the list's Input().     *
    779  *                                                                                             *
    780  * INPUT:   none                                                                               *
    781  *                                                                                             *
    782  * OUTPUT:  true = an item needs redrawing, false = no items need redrawing                    *
    783  *                                                                                             *
    784  * WARNINGS:   It is assumed 'this' is the head of the list.                                   *
    785  *                                                                                             *
    786  * HISTORY:                                                                                    *
    787  *   01/03/1995 MML : Created.                                                                 *
    788  *=============================================================================================*/
    789 int GadgetClass::Is_List_To_Redraw(void)
    790 {
    791 	GadgetClass *gadget = this;
    792 
    793 	while (gadget != NULL) {
    794 		if (gadget->IsToRepaint)
    795 			return (true);
    796 		gadget = gadget->Get_Next();
    797 	}
    798 	return (false);
    799 }
    800 
    801