GADGET.CPP 46 KB

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