GADGET.CPP 47 KB

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