870 lines
46 KiB
C++
870 lines
46 KiB
C++
//
|
|
// Copyright 2020 Electronic Arts Inc.
|
|
//
|
|
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
|
|
// software: you can redistribute it and/or modify it under the terms of
|
|
// the GNU General Public License as published by the Free Software Foundation,
|
|
// either version 3 of the License, or (at your option) any later version.
|
|
|
|
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
|
// in the hope that it will be useful, but with permitted additional restrictions
|
|
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
|
// distributed with this program. You should have received a copy of the
|
|
// GNU General Public License along with permitted additional restrictions
|
|
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
|
|
|
/* $Header: /CounterStrike/GADGET.CPP 1 3/03/97 10:24a Joe_bostic $ */
|
|
/***********************************************************************************************
|
|
*** 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 ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : Command & Conquer *
|
|
* *
|
|
* File Name : GADGET.CPP *
|
|
* *
|
|
* Programmer : Maria del Mar McCready Legg *
|
|
* Joe L. Bostic *
|
|
* *
|
|
* Start Date : 01/03/95 *
|
|
* *
|
|
* Last Update : August 1, 1996 [JLB] *
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* GadgetClass::Action -- Base action for gadget. *
|
|
* GadgetClass::Clear_Focus -- Clears the focus if this gadget has it. *
|
|
* GadgetClass::Delete_List -- Deletes all gadget objects in list. *
|
|
* GadgetClass::Disable -- Disables the gadget from input processing. *
|
|
* GadgetClass::Draw_All -- Forces all gadgets in list to be redrawn. *
|
|
* GadgetClass::Draw_Me -- Gadget redraw action (flag control). *
|
|
* GadgetClass::Enable -- Enables the gadget. *
|
|
* GadgetClass::Extract_Gadget -- Sweeps through the gadget chain to find gadget specified. *
|
|
* GadgetClass::Flag_To_Redraw -- Flags this gadget to be redrawn. *
|
|
* GadgetClass::GadgetClass -- Constructor for gadget object. *
|
|
* GadgetClass::GadgetClass -- Default constructor for a gadget class object. *
|
|
* GadgetClass::Get_Next -- Returns a pointer to the next gadget in the chain. *
|
|
* GadgetClass::Get_Prev -- Fetches a pointer to the previous gadget. *
|
|
* GadgetClass::Has_Focus -- Checks if this object currently has the keyboard focus. *
|
|
* GadgetClass::Remove -- Removes the specified gadget from the list. *
|
|
* GadgetClass::Set_Focus -- Sets focus to this gadget. *
|
|
* GadgetClass::Sticky_Process -- Handles the sticky flag processing. *
|
|
* GadgetClass::~GadgetClass -- Destructor for gadget object. *
|
|
* GadgetClass::Is_List_To_Redraw -- tells if any gadget in the list needs redrawing *
|
|
* GadgetClass::GadgetClass -- Constructor for the gadget object. *
|
|
* GadgetClass::Set_Position -- Set the coordinate position of this gadget. *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#include "function.h"
|
|
|
|
|
|
/*
|
|
** This records the current gadget the the gadget system is "stuck on". Such a
|
|
** gadget will be processed to the exclusion of all others until the mouse button
|
|
** is no longer pressed.
|
|
*/
|
|
GadgetClass * GadgetClass::StuckOn = 0;
|
|
|
|
/*
|
|
** This is a copy of a pointer to the last list used by the gadget input system.
|
|
** If a change of list is detected, then all gadgets are forced to be redrawn.
|
|
*/
|
|
GadgetClass * GadgetClass::LastList = 0;
|
|
|
|
|
|
/*
|
|
** This points to the gadget that is intercepting all keyboard events.
|
|
*/
|
|
GadgetClass * GadgetClass::Focused = 0;
|
|
|
|
|
|
/*
|
|
** This points to the current color scheme for drawing all gadgets.
|
|
*/
|
|
static RemapControlType _GreyScheme = {15};
|
|
RemapControlType * GadgetClass::ColorScheme = &_GreyScheme;
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::GadgetClass -- Constructor for gadget object. *
|
|
* *
|
|
* This is the normal constructor for gadget objects. A gadget object is only concerned *
|
|
* with the region on the screen to considered "its own" as well as the flags that tell *
|
|
* what mouse action should be recognized when the mouse is over this screen area. *
|
|
* *
|
|
* INPUT: x,y -- Coordinates (in pixels) of the upper left hand corner of the region that *
|
|
* will be "owned" by this gadget. *
|
|
* *
|
|
* w,h -- Width and height (in pixels) of this gadget's region. *
|
|
* *
|
|
* flags -- The flags (mouse conditions) that will cause this gadget's action *
|
|
* function to be called. *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/03/1995 MML : Created. *
|
|
*=============================================================================================*/
|
|
GadgetClass::GadgetClass(int x, int y, int w, int h, unsigned flags, int sticky) :
|
|
X(x), Y(y), Width(w), Height(h), IsToRepaint(false), IsSticky(sticky), IsDisabled(false), Flags(flags)
|
|
{
|
|
if (IsSticky) {
|
|
Flags |= LEFTPRESS|LEFTRELEASE;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::GadgetClass -- Constructor for the gadget object. *
|
|
* *
|
|
* This is the copy constructor for the gadget object. It will try to duplicate the *
|
|
* righthand gadget. *
|
|
* *
|
|
* INPUT: gadget -- Reference to the initilization gadget. *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/01/1996 JLB : Created. *
|
|
*=============================================================================================*/
|
|
GadgetClass::GadgetClass(GadgetClass const & gadget) :
|
|
X(gadget.X),
|
|
Y(gadget.Y),
|
|
Width(gadget.Width),
|
|
Height(gadget.Height),
|
|
IsToRepaint(gadget.IsToRepaint),
|
|
IsSticky(gadget.IsSticky),
|
|
IsDisabled(gadget.IsDisabled),
|
|
Flags(gadget.Flags)
|
|
{
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::~GadgetClass -- Destructor for gadget object. *
|
|
* *
|
|
* This is the destructor for the gadget object. It will clear the focus from this gadget *
|
|
* if this gadget currently has the focus. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 07/08/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
GadgetClass::~GadgetClass(void)
|
|
{
|
|
if (Has_Focus()) {
|
|
Clear_Focus();
|
|
}
|
|
|
|
if (this == StuckOn) {
|
|
StuckOn = NULL;
|
|
}
|
|
|
|
if (this == LastList) {
|
|
LastList = NULL;
|
|
}
|
|
|
|
if (this == Focused) {
|
|
Focused = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
* GADGETCLASS::CLICKEDON -- If a mouse click is detected within gadget's *
|
|
* area and the appropriate flag is set, then call Action(). *
|
|
* *
|
|
* INPUT: int key, int mousex, int mousey *
|
|
* *
|
|
* OUTPUT: true or false *
|
|
* *
|
|
* WARNINGS: none. *
|
|
* *
|
|
* HISTORY: 01/03/1995 MML : Created. *
|
|
*=========================================================================*/
|
|
int GadgetClass::Clicked_On(KeyNumType & key, unsigned flags, int mousex, int mousey)
|
|
{
|
|
/*
|
|
** Set flags to match only those events that occur AND are being looked for. If
|
|
** the result is NULL, then we know that this button should be ignored.
|
|
*/
|
|
flags &= Flags;
|
|
|
|
/*
|
|
** If keyboard input should be processed by this "gadget" and keyboard input is
|
|
** detected, then always call the action function. It is up to the action function
|
|
** in this case to either ignore the keyboard input or not.
|
|
**
|
|
** For mouse actions, check to see if the mouse is in the region of the button
|
|
** before calling the associated action function. This is the typical action for
|
|
** buttons.
|
|
*/
|
|
if (this == StuckOn ||
|
|
(flags & KEYBOARD) ||
|
|
(flags && (mousex - X) < Width && (mousey - Y) < Height)) {
|
|
|
|
return(Action(flags, key));
|
|
}
|
|
return(false);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Enable -- Enables the gadget. *
|
|
* *
|
|
* This function enables the gadget. An enabled gadget will be processed for input *
|
|
* purposes. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/15/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Enable(void)
|
|
{
|
|
IsDisabled = false;
|
|
IsToRepaint = true;
|
|
Clear_Focus();
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Disable -- Disables the gadget from input processing. *
|
|
* *
|
|
* This routine will disable the gadget. A disabled gadget might be rendered, but is *
|
|
* ignored for input processing. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/15/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Disable(void)
|
|
{
|
|
IsDisabled = true;
|
|
IsToRepaint = true;
|
|
Clear_Focus();
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Remove -- Removes the specified gadget from the list. *
|
|
* *
|
|
* Use this routine if an individual gadget needs to be removed from the list of gadgets. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: bool; Was the specified gadget found and removed? A false indicates that the *
|
|
* gadget wasn't in the list. *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/15/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
GadgetClass * GadgetClass::Remove(void)
|
|
{
|
|
Clear_Focus();
|
|
return(GadgetClass *)LinkClass::Remove();
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Get_Next -- Returns a pointer to the next gadget in the chain. *
|
|
* *
|
|
* This returns with the next gadget's pointer. It is identical to the base Get_Next() *
|
|
* function, but returns a pointer to a GadgetClass object. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: Returns with a pointer to the next gadget in the list. *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/15/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
GadgetClass * GadgetClass::Get_Next(void) const
|
|
{
|
|
return(GadgetClass*)LinkClass::Get_Next();
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Get_Prev -- Fetches a pointer to the previous gadget. *
|
|
* *
|
|
* This routine will return the previous gadget in the list. It is identical to the base *
|
|
* function Get_Prev, but returns a pointer to a GadgetClass object. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: Returns with a pointer to the previous gadget in the list. *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/15/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
GadgetClass * GadgetClass::Get_Prev(void) const
|
|
{
|
|
return(GadgetClass*)LinkClass::Get_Prev();
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Delete_List -- Deletes all gadget objects in list. *
|
|
* *
|
|
* This function will delete all gadgets in the list. It is the counterpart to the *
|
|
* Create_One_Of functions. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: Any references to these gadget become invalidated by this routine. *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/15/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Delete_List(void)
|
|
{
|
|
GadgetClass * g = this;
|
|
|
|
/*
|
|
** Move to head of the list.
|
|
*/
|
|
while (g->Get_Prev()) {
|
|
g = g->Get_Prev();
|
|
}
|
|
|
|
/*
|
|
** First delete all the gadgets following the first one. The reason the first one
|
|
** is kept around is that sometimes deleting one gadget will result in related gadgets
|
|
** in the same list also being deleted. The first gadget will always contain the
|
|
** correct gadget pointer.
|
|
*/
|
|
while (g) {
|
|
g->Clear_Focus();
|
|
|
|
GadgetClass * temp = g;
|
|
g = g->Get_Next();
|
|
delete temp;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Action -- Base action for gadget. *
|
|
* *
|
|
* This handles the base level action that a gadget performs when a qualifying input event *
|
|
* is detected. This sets the redraw flag and returns true (to stop further processing). *
|
|
* If no qualifying input event was detected, but this routine was called anyway, then *
|
|
* don't perform any action. The call to this routine, in that case, must have been forced *
|
|
* for some other reason. *
|
|
* *
|
|
* INPUT: flag -- The input event bits that qualify for this gadget. A NULL indicates that *
|
|
* no qualifying event occurred. *
|
|
* *
|
|
* OUTPUT: bool; Should further gadget list processing be aborted? *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/15/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
int GadgetClass::Action(unsigned flags, KeyNumType &)
|
|
{
|
|
/*
|
|
** If any of the event flags are active, then this indicates that something probably
|
|
** has changed the gadget. Flag the gadget to be redrawn. Also, make sure that
|
|
** any sticky flags are cleared up.
|
|
*/
|
|
if (flags) {
|
|
IsToRepaint = true;
|
|
Sticky_Process(flags);
|
|
return(true);
|
|
}
|
|
return(false);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Draw_Me -- Gadget redraw action (flag control). *
|
|
* *
|
|
* At this level, there is no actual rendering taking place with the call to Draw_Me, but *
|
|
* the IsToRepaint flag must be cleared. Derived objects will call this routine and if it *
|
|
* returns true, they will perform their custom rendering. *
|
|
* *
|
|
* INPUT: forced -- Is this redraw forced by outside circumstances? *
|
|
* *
|
|
* OUTPUT: bool; Should the gadget imagery be redrawn? *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/14/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
int GadgetClass::Draw_Me(int forced)
|
|
{
|
|
if (forced || IsToRepaint) {
|
|
IsToRepaint = false;
|
|
return(true);
|
|
}
|
|
return(false);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Draw_All -- Forces all gadgets in list to be redrawn. *
|
|
* *
|
|
* Use this function to cause all gadget in the list to be redrawn regardless of the state *
|
|
* of the IsToRepaint flag. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/03/1995 MML : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Draw_All(bool forced)
|
|
{
|
|
GadgetClass * gadget = this;
|
|
|
|
while (gadget != NULL) {
|
|
gadget->Draw_Me(forced);
|
|
gadget = gadget->Get_Next();
|
|
}
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
* GADGETCLASS::PROCESSLIST -- Check list for a mouse click within a gadget*
|
|
* *
|
|
* INPUT: none. *
|
|
* *
|
|
* OUTPUT: key pressed. *
|
|
* *
|
|
* WARNINGS: none. *
|
|
* *
|
|
* HISTORY: 01/03/1995 MML : Created. *
|
|
*=========================================================================*/
|
|
KeyNumType GadgetClass::Input(void)
|
|
{
|
|
int mousex, mousey;
|
|
KeyNumType key;
|
|
unsigned flags;
|
|
int forced = false;
|
|
|
|
/*
|
|
** Record this list so that a forced redraw only occurs the FIRST time the
|
|
** gadget list is passed to this routine.
|
|
*/
|
|
if (LastList != this) {
|
|
LastList = this;
|
|
forced = true;
|
|
StuckOn = NULL;
|
|
Focused = NULL;
|
|
}
|
|
|
|
/*
|
|
** Fetch any pending keyboard input.
|
|
*/
|
|
key = Keyboard->Check();
|
|
if (key != 0) {
|
|
key = Keyboard->Get();
|
|
}
|
|
|
|
#ifdef WIN32
|
|
#ifdef CHEAT_KEYS
|
|
if (key == KN_K && !Debug_Map && (Debug_Flag || Debug_Playtest)) {
|
|
/*
|
|
** time to create a screen shot using the PCX code (if it works)
|
|
*/
|
|
if (!Debug_MotionCapture) {
|
|
GraphicBufferClass temp_page( SeenBuff.Get_Width(),
|
|
SeenBuff.Get_Height(),
|
|
NULL,
|
|
SeenBuff.Get_Width() * SeenBuff.Get_Height());
|
|
CDFileClass file;
|
|
char filename[30];
|
|
|
|
// Hide_Mouse();
|
|
SeenBuff.Blit(temp_page);
|
|
// Show_Mouse();
|
|
for (int lp = 0; lp < 99; lp ++) {
|
|
sprintf(filename, "scrsht%02d.pcx", lp);
|
|
file.Set_Name(filename);
|
|
if (!file.Is_Available()) break;
|
|
}
|
|
|
|
file.Cache(200000);
|
|
Write_PCX_File(file, temp_page, & GamePalette);
|
|
Sound_Effect(VOC_BEEP);
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
/*
|
|
** For mouse button clicks, the mouse position is actually held in the MouseQ...
|
|
** globals rather than their normal Mouse... globals. This is because we need to
|
|
** know the position of the mouse at the exact instant when the click occurred
|
|
** rather the the mouse position at the time we get around to this function.
|
|
*/
|
|
if (((key&0xFF) == KN_LMOUSE) || ((key&0xFF) == KN_RMOUSE)) {
|
|
mousex = Keyboard->MouseQX;
|
|
mousey = Keyboard->MouseQY;
|
|
} else {
|
|
mousex = Get_Mouse_X();
|
|
mousey = Get_Mouse_Y();
|
|
}
|
|
|
|
/*
|
|
** Set the mouse button state flags. These will be passed to the individual
|
|
** buttons so that they can determine what action to perform (if any).
|
|
*/
|
|
flags = 0;
|
|
if (key) {
|
|
if (key == KN_LMOUSE) {
|
|
flags |= LEFTPRESS;
|
|
}
|
|
if (key == KN_RMOUSE) {
|
|
flags |= RIGHTPRESS;
|
|
}
|
|
if (key == (KN_LMOUSE | KN_RLSE_BIT)) {
|
|
flags |= LEFTRELEASE;
|
|
}
|
|
if (key == (KN_RMOUSE | KN_RLSE_BIT)) {
|
|
flags |= RIGHTRELEASE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** If the mouse wasn't responsible for this key code, then it must be from
|
|
** the keyboard. Flag this fact.
|
|
*/
|
|
if (key && !flags) {
|
|
flags |= KEYBOARD;
|
|
}
|
|
|
|
/*
|
|
** Mouse button up or down action is ignored if there is a keyboard event. This
|
|
** allows keyboard events to fall through normally even if the mouse is over a
|
|
** gadget that is flagged for LEFTUP or RIGHTUP.
|
|
*/
|
|
if (!key) {
|
|
|
|
/*
|
|
** Check for the mouse being held down. We can't use the normal input system
|
|
** for this, so we must examine the actual current state of the mouse
|
|
** buttons. As a side note, if we determine that the mouse button isn't being
|
|
** held down, then we automatically know that it must be up -- set the flag
|
|
** accordingly.
|
|
*/
|
|
if (Keyboard->Down(KN_LMOUSE)) {
|
|
flags |= LEFTHELD;
|
|
} else {
|
|
flags |= LEFTUP;
|
|
}
|
|
if (Keyboard->Down(KN_RMOUSE)) {
|
|
flags |= RIGHTHELD;
|
|
} else {
|
|
flags |= RIGHTUP;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** If "sticky" processing is active, then only process the stuck gadget.
|
|
*/
|
|
if (StuckOn) {
|
|
StuckOn->Draw_Me(false);
|
|
GadgetClass * oldstuck = StuckOn;
|
|
StuckOn->Clicked_On(key, flags, mousex, mousey);
|
|
if (StuckOn) {
|
|
StuckOn->Draw_Me(false);
|
|
} else {
|
|
oldstuck->Draw_Me(false);
|
|
}
|
|
} else {
|
|
|
|
/*
|
|
** If there is a gadget that has the keyboard focus, then route all keyboard
|
|
** events to it.
|
|
*/
|
|
if (Focused && (flags & KEYBOARD)) {
|
|
Focused->Draw_Me(false);
|
|
Focused->Clicked_On(key, flags, mousex, mousey);
|
|
if (Focused) {
|
|
Focused->Draw_Me(false);
|
|
}
|
|
} else {
|
|
|
|
/*
|
|
** Sweep through all the buttons in the chain and pass the current button state
|
|
** and keyboard input data to them. These routines will detect whether they should
|
|
** perform some action and return a flag to this effect. They also have the option
|
|
** of changing the key value so that an appropriate return value is use for this
|
|
** processing routine.
|
|
*/
|
|
GadgetClass * next_button = this;
|
|
while (next_button != NULL) {
|
|
|
|
/*
|
|
** Maybe redraw the button if it needs to or is being forced to redraw.
|
|
*/
|
|
next_button->Draw_Me(forced);
|
|
|
|
if (!next_button->IsDisabled) {
|
|
|
|
/*
|
|
** Process this button. If the button was recognized and action was
|
|
** performed, then bail from further processing (speed reasons?).
|
|
*/
|
|
if (next_button->Clicked_On(key, flags, mousex, mousey)) {
|
|
|
|
/*
|
|
** Some buttons will require repainting when they perform some action.
|
|
** Do so at this time.
|
|
*/
|
|
next_button->Draw_Me(false);
|
|
break;
|
|
}
|
|
}
|
|
|
|
next_button = next_button->Get_Next();
|
|
}
|
|
}
|
|
}
|
|
return(key);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Extract_Gadget -- Sweeps through the gadget chain to find gadget specified. *
|
|
* *
|
|
* This examines the gadget list looking for on that has the same ID as specified. If that *
|
|
* gadget was found, then a pointer to it is returned. Since only ControlClass gadgets *
|
|
* or ones derived from it can have an ID value, we know that the returned pointer is at *
|
|
* least of the ControlClass type. *
|
|
* *
|
|
* INPUT: id -- The ID number to scan for. Zero is not a legal ID number and if passed in, *
|
|
* a NULL will always be returned. *
|
|
* *
|
|
* OUTPUT: Returns with a pointer to the ControlClass gadget that has the matching ID number. *
|
|
* If no matching gadget was found, then NULL is returned. *
|
|
* *
|
|
* WARNINGS: If there happens to be more than one gadget with a matching ID, this routine *
|
|
* will return a pointer to the first one only. *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/16/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
ControlClass * GadgetClass::Extract_Gadget(unsigned id)
|
|
{
|
|
GadgetClass * g = this;
|
|
|
|
if (id != 0) {
|
|
while (g != NULL) {
|
|
if (g->Get_ID() == id) {
|
|
return((ControlClass *)g);
|
|
}
|
|
g = g->Get_Next();
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Flag_To_Redraw -- Flags this gadget to be redrawn. *
|
|
* *
|
|
* Use this routine to flag the gadget to be redrawn. A gadget so flagged will have its *
|
|
* Draw_Me function called at the next available opportunity. Usually, this is the next *
|
|
* time the Input() function is called. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/16/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Flag_To_Redraw(void)
|
|
{
|
|
IsToRepaint = true;
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Sticky_Process -- Handles the sticky flag processing. *
|
|
* *
|
|
* This function examines the event flags and handles any "sticky" processing required. *
|
|
* Sticky processing is when the button is flagged with the "IsSticky" bit and it will *
|
|
* be processed to the exclusion of all other gadgets while the mouse button is held *
|
|
* down. *
|
|
* *
|
|
* INPUT: flags -- The event flags that triggered the call to this routine. *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/16/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Sticky_Process(unsigned flags)
|
|
{
|
|
if (IsSticky && (flags & LEFTPRESS)) {
|
|
StuckOn = this;
|
|
}
|
|
if (StuckOn == this && (flags & LEFTRELEASE)) {
|
|
StuckOn = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Set_Focus -- Sets focus to this gadget. *
|
|
* *
|
|
* This will set the focus to this gadget regardless of any current focus setting. If there *
|
|
* is another gadget that has focus, it will have its focus cleared before this gadget will *
|
|
* get the focus. A focused gadget is one that has all keyboard input routed to it. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/25/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Set_Focus(void)
|
|
{
|
|
if (Focused) {
|
|
Focused->Flag_To_Redraw();
|
|
Focused->Clear_Focus();
|
|
}
|
|
Flags |= KEYBOARD;
|
|
Focused = this;
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Clear_Focus -- Clears the focus if this gadget has it. *
|
|
* *
|
|
* Use this function to clear the focus for the gadget. If the gadget doesn't currently *
|
|
* have focus, then this routine will do nothing. For added functionality, overload this *
|
|
* virtual function so that gadget specific actions may be take when focus is lost. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/25/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Clear_Focus(void)
|
|
{
|
|
if (Focused == this) {
|
|
Flags &= ~KEYBOARD;
|
|
Focused = 0;
|
|
}
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Has_Focus -- Checks if this object currently has the keyboard focus. *
|
|
* *
|
|
* If this object has the keyboard focus, then this routine will return true. When the *
|
|
* gadget has keyboard focus, all keyboard events get routed to the gadget. *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: bool; Does this gadget have the keyboard focus? *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/21/1995 JLB : Created. *
|
|
*=============================================================================================*/
|
|
bool GadgetClass::Has_Focus(void)
|
|
{
|
|
return(this == Focused);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Is_List_To_Redraw -- tells if any gadget in the list needs redrawing *
|
|
* *
|
|
* This function is mostly for supporting HidPage drawing. If it returns true, it means *
|
|
* the application needs to re-blit the HidPage forward, after calling the list's Input(). *
|
|
* *
|
|
* INPUT: none *
|
|
* *
|
|
* OUTPUT: true = an item needs redrawing, false = no items need redrawing *
|
|
* *
|
|
* WARNINGS: It is assumed 'this' is the head of the list. *
|
|
* *
|
|
* HISTORY: *
|
|
* 01/03/1995 MML : Created. *
|
|
*=============================================================================================*/
|
|
int GadgetClass::Is_List_To_Redraw(void)
|
|
{
|
|
GadgetClass * gadget = this;
|
|
|
|
while (gadget != NULL) {
|
|
if (gadget->IsToRepaint) {
|
|
return (true);
|
|
}
|
|
gadget = gadget->Get_Next();
|
|
}
|
|
return (false);
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* GadgetClass::Set_Position -- Set the coordinate position of this gadget. *
|
|
* *
|
|
* This routine helps with moving a gadget's location. It will set the gadgets upper *
|
|
* left corner to the pixel location specified. *
|
|
* *
|
|
* INPUT: x,y -- The X and Y position to put the gadget's upper left corner to. *
|
|
* *
|
|
* OUTPUT: none *
|
|
* *
|
|
* WARNINGS: none *
|
|
* *
|
|
* HISTORY: *
|
|
* 08/01/1996 JLB : Created. *
|
|
*=============================================================================================*/
|
|
void GadgetClass::Set_Position(int x, int y)
|
|
{
|
|
X = x;
|
|
Y = y;
|
|
}
|
|
|