CnC_Remastered_Collection

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

GADGET.CPP (47640B)


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