SLIDER.CPP 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. ** Command & Conquer(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: F:\projects\c&c\vcs\code\slider.cpv 2.17 16 Oct 1995 16:51:54 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 : SLIDER.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : 01/15/95 *
  30. * *
  31. * Last Update : January 16, 1995 [JLB] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * SliderClass::Action -- Handles input processing for the slider. *
  36. * SliderClass::Bump -- Bumps the slider one "thumb size" up or down. *
  37. * SliderClass::Recalc_Thumb -- Recalculates the thumb pixel size and starting offset. *
  38. * SliderClass::Set_Maximum -- Sets the maximum value for this slider. *
  39. * SliderClass::Set_Thumb_Size -- Sets the size fo the thumb in "slider units". *
  40. * SliderClass::Set_Value -- Sets the current thumb position for the slider. *
  41. * SliderClass::SliderClass -- Normal constructor for a slider (with thumb) gadget. *
  42. * SliderClass::Step -- Steps the slider one value up or down. *
  43. * SliderClass::Draw_Thumb -- Draws the "thumb" for this slider. *
  44. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  45. #include "function.h"
  46. #include "slider.h"
  47. /***********************************************************************************************
  48. * SliderClass::SliderClass -- Normal constructor for a slider (with thumb) gadget. *
  49. * *
  50. * This is the normal constructor for the slider gadget. *
  51. * *
  52. * INPUT: id -- The ID number to assign to this gadget. *
  53. * x,y -- The pixel coordinate of the upper left corner for this gadget. *
  54. * w,h -- The width and height of the slider gadget. The slider automatically *
  55. * adapts for horizontal or vertical operation depending on which of these *
  56. * dimensions is greater. *
  57. * OUTPUT: none *
  58. * WARNINGS: none *
  59. * HISTORY: 01/15/1995 JLB : Created. *
  60. *=============================================================================================*/
  61. SliderClass::SliderClass(unsigned id, int x, int y, int w, int h, int belong_to_list)
  62. : GaugeClass(id, x, y, w, h)
  63. {
  64. BelongToList = belong_to_list ? true : false;
  65. PlusGadget = 0;
  66. MinusGadget = 0;
  67. if (!BelongToList) {
  68. PlusGadget = new ShapeButtonClass(id, MixFileClass::Retrieve("BTN-PLUS.SHP"), X+Width+2, Y);
  69. MinusGadget = new ShapeButtonClass(id, MixFileClass::Retrieve("BTN-MINS.SHP"), X-6, Y);
  70. if (PlusGadget) {
  71. PlusGadget->Make_Peer(*this);
  72. PlusGadget->Add(*this);
  73. PlusGadget->Flag_To_Redraw();
  74. }
  75. if (MinusGadget) {
  76. MinusGadget->Make_Peer(*this);
  77. MinusGadget->Add(*this);
  78. MinusGadget->Flag_To_Redraw();
  79. }
  80. }
  81. Set_Thumb_Size(1);
  82. Recalc_Thumb();
  83. /*
  84. ** Gauges have at least 2 colors, but sliders should only have one.
  85. */
  86. IsColorized = 0;
  87. }
  88. virtual SliderClass::~SliderClass(void)
  89. {
  90. if (PlusGadget) {
  91. delete PlusGadget;
  92. PlusGadget = 0;
  93. }
  94. if (MinusGadget) {
  95. delete MinusGadget;
  96. MinusGadget = 0;
  97. }
  98. }
  99. /***********************************************************************************************
  100. * SliderClass::Set_Maximum -- Sets the maximum value for this slider. *
  101. * *
  102. * This sets the maximum value that the slider can be set at. The maximum value controls *
  103. * the size of the thumb and the resolution of the thumb's movement. *
  104. * *
  105. * INPUT: value -- The value to set for the slider's maximum. *
  106. * OUTPUT: bool; Was the maximum value changed? A false indicates a set to the value it *
  107. * is currently set to already. *
  108. * WARNINGS: none *
  109. * HISTORY: 01/15/1995 JLB : Created. *
  110. *=============================================================================================*/
  111. int SliderClass::Set_Maximum(int value)
  112. {
  113. if (GaugeClass::Set_Maximum(value)) {
  114. Recalc_Thumb();
  115. return(true);
  116. }
  117. return(false);
  118. }
  119. /***********************************************************************************************
  120. * SliderClass::Set_Thumb_Size -- Sets the size fo the thumb in "slider units". *
  121. * *
  122. * This routine will set the size of the thumb as it relates to the maximum value the *
  123. * slider can achieve. This serves to display a proportionally sized thumb as well as *
  124. * control how the slider "bumps" up or down. *
  125. * *
  126. * INPUT: value -- The new value of the thumb. It should never be larger than the slider *
  127. * maximum. *
  128. * OUTPUT: none *
  129. * WARNINGS: none *
  130. * HISTORY: 01/15/1995 JLB : Created. *
  131. *=============================================================================================*/
  132. void SliderClass::Set_Thumb_Size(int value)
  133. {
  134. Thumb = MIN(value, MaxValue);
  135. Thumb = MAX(Thumb, 1);
  136. Flag_To_Redraw();
  137. Recalc_Thumb();
  138. }
  139. /***********************************************************************************************
  140. * SliderClass::Set_Value -- Sets the current thumb position for the slider. *
  141. * *
  142. * This routine will set the thumb position for the slider. *
  143. * *
  144. * INPUT: value -- The position to set the slider. This position is relative to the maximum *
  145. * value for the slider. *
  146. * *
  147. * OUTPUT: bool; Was the slider thumb position changed at all? *
  148. * WARNINGS: none *
  149. * HISTORY: 01/15/1995 JLB : Created. *
  150. *=============================================================================================*/
  151. int SliderClass::Set_Value(int value)
  152. {
  153. value = MIN(value, MaxValue-Thumb);
  154. if (GaugeClass::Set_Value(value)) {
  155. Recalc_Thumb();
  156. return(true);
  157. }
  158. return(false);
  159. }
  160. /***********************************************************************************************
  161. * SliderClass::Recalc_Thumb -- Recalculates the thumb pixel size and starting offset. *
  162. * *
  163. * This takes the current thumb logical size and starting value and calculates the pixel *
  164. * size and starting offset accordingly. This function should be called whenever one of *
  165. * these elements has changed. *
  166. * *
  167. * INPUT: none *
  168. * OUTPUT: none *
  169. * WARNINGS: none *
  170. * HISTORY: 01/15/1995 JLB : Created. *
  171. *=============================================================================================*/
  172. void SliderClass::Recalc_Thumb(void)
  173. {
  174. int length = IsHorizontal ? Width : Height;
  175. int size = Fixed_To_Cardinal(length, Cardinal_To_Fixed(MaxValue, Thumb));
  176. ThumbSize = MAX(size, 4);
  177. int start = Fixed_To_Cardinal(length, Cardinal_To_Fixed(MaxValue, CurValue));
  178. ThumbStart = MIN(start, length-ThumbSize);
  179. }
  180. /***********************************************************************************************
  181. * SliderClass::Action -- Handles input processing for the slider. *
  182. * *
  183. * This routine is called when a qualifying input event has occured. This routine will *
  184. * process that event and make any adjustments to the slider as necessary. *
  185. * *
  186. * INPUT: flags -- Flag bits that tell the input event that caused this function to *
  187. * be called. *
  188. * key -- Reference to the key that caused the input event. *
  189. * OUTPUT: bool; Was the event consumed and further processing of the gadget list should be *
  190. * aborted? *
  191. * WARNINGS: none *
  192. * HISTORY: 01/15/1995 JLB : Created. *
  193. *=============================================================================================*/
  194. int SliderClass::Action(unsigned flags, KeyNumType &key)
  195. {
  196. /*
  197. ** Handle the mouse click in a special way. If the click was not on the thumb, then
  198. ** jump the thumb position one "step" in the appropriate direction. Otherwise, let normal
  199. ** processing take place -- the slider then "sticks" and the thumb moves according to
  200. ** mouse position.
  201. */
  202. if (flags & LEFTPRESS) {
  203. int mouse; // Mouse pixel position.
  204. int edge; // Edge of slider.
  205. if (IsHorizontal) {
  206. mouse = Get_Mouse_X();
  207. edge = X;
  208. } else {
  209. mouse = Get_Mouse_Y();
  210. edge = Y;
  211. }
  212. edge += 1;
  213. /*
  214. ** Clicking outside the thumb: invoke parent's Action to process flags etc,
  215. ** but turn off the event & return true so processing stops at this button.
  216. */
  217. if (mouse < edge+ThumbStart) {
  218. Bump(true);
  219. GaugeClass::Action(0, key);
  220. key = KN_NONE;
  221. return(true);
  222. } else {
  223. if (mouse > edge+ThumbStart+ThumbSize) {
  224. Bump(false);
  225. GaugeClass::Action(0, key);
  226. key = KN_NONE;
  227. return(true);
  228. } else {
  229. GaugeClass::Action(flags, key);
  230. key = KN_NONE;
  231. return(true);
  232. }
  233. }
  234. }
  235. /*
  236. ** CHANGE GAUGECLASS::ACTION -- REMOVE (LEFTRELEASE) FROM IF STMT
  237. */
  238. return(GaugeClass::Action(flags, key));
  239. }
  240. /***********************************************************************************************
  241. * SliderClass::Bump -- Bumps the slider one "thumb size" up or down. *
  242. * *
  243. * This support function will bump the slider one "step" or the size of the thumb up or *
  244. * down as specified. It is typically called when the slider is clicked outside of the *
  245. * thumb region but still inside of the slider. *
  246. * *
  247. * INPUT: up -- Should the bump be to increase the current position? *
  248. * OUTPUT: bool; Was the slider changed at all? A false indicates that the slider is already *
  249. * at one end or the other. *
  250. * WARNINGS: none *
  251. * HISTORY: 01/15/1995 JLB : Created. *
  252. *=============================================================================================*/
  253. int SliderClass::Bump(int up)
  254. {
  255. if (up) {
  256. return(Set_Value(CurValue - Thumb));
  257. }
  258. return(Set_Value(CurValue + Thumb));
  259. }
  260. /***********************************************************************************************
  261. * SliderClass::Step -- Steps the slider one value up or down. *
  262. * *
  263. * This routine will move the slider thumb one step in the direction specified. *
  264. * *
  265. * INPUT: up -- Should the step be up (i.e., forward)? *
  266. * OUTPUT: bool; Was the slider changed at all? A false indicates that the slider is already *
  267. * at one end or the other. *
  268. * WARNINGS: none *
  269. * HISTORY: 01/15/1995 JLB : Created. *
  270. *=============================================================================================*/
  271. int SliderClass::Step(int up)
  272. {
  273. if (up) {
  274. return(Set_Value(CurValue - 1));
  275. }
  276. return(Set_Value(CurValue + 1));
  277. }
  278. /***********************************************************************************************
  279. * SliderClass::Draw_Thumb -- Draws the "thumb" for this slider. *
  280. * *
  281. * This will draw the thumb graphic for this slider. Sometimes the thumb requires special *
  282. * drawing, thus the need for this function separate from the normal Draw_Me function. *
  283. * *
  284. * INPUT: none *
  285. * OUTPUT: none *
  286. * WARNINGS: The mouse is guaranteed to be hidden when this routine is called. *
  287. * HISTORY: 01/16/1995 JLB : Created. *
  288. *=============================================================================================*/
  289. void SliderClass::Draw_Thumb(void)
  290. {
  291. if (IsHorizontal) {
  292. Draw_Box(X+ThumbStart, Y, ThumbSize, Height, BOXSTYLE_GREEN_RAISED, true);
  293. } else {
  294. Draw_Box(X, Y+ThumbStart, Width, ThumbSize, BOXSTYLE_GREEN_RAISED, true);
  295. }
  296. }
  297. /***********************************************************************************************
  298. * SliderClass::Draw_Me -- Draws the body of the gauge. *
  299. * *
  300. * This routine will draw the body of the gauge if necessary. *
  301. * *
  302. * INPUT: forced -- Should the gauge be redrawn regardless of the current redraw flag? *
  303. * OUTPUT: bool; Was the gauge redrawn? *
  304. * WARNINGS: none *
  305. * HISTORY: 01/16/1995 JLB : Created. *
  306. *=============================================================================================*/
  307. int SliderClass::Draw_Me(int forced)
  308. {
  309. if (BelongToList) {
  310. if (ControlClass::Draw_Me(forced)) {
  311. /*
  312. ===================== Hide the mouse =====================
  313. */
  314. if (LogicPage == &SeenBuff) {
  315. Conditional_Hide_Mouse(X, Y, X+Width, Y+Height);
  316. }
  317. /*
  318. =========== Draw the body & set text color ===============
  319. */
  320. Draw_Box (X, Y, Width, Height, BOXSTYLE_GREEN_DOWN, true);
  321. // if (IsHorizontal) {
  322. // LogicPage->Fill_Rect(X, Y+1, X+Width-1, Y+Height-2, 141);
  323. // LogicPage->Draw_Line(X, Y, X+Width-1, Y, 140); // top
  324. // LogicPage->Draw_Line(X, Y+Height, X+Width, Y+Height, 159); // bottom
  325. // } else {
  326. // LogicPage->Fill_Rect(X+1, Y, X+Width-2, Y+Height-1, 141);
  327. // LogicPage->Draw_Line(X, Y, X, Y+Height, 140); // left
  328. // LogicPage->Draw_Line(X+Width-1, Y, X+Width-1, Y+Height, 159); // right
  329. // }
  330. Draw_Thumb();
  331. /*
  332. =================== Display the mouse ===================
  333. */
  334. if (LogicPage == &SeenBuff) {
  335. Conditional_Show_Mouse();
  336. }
  337. return(true);
  338. }
  339. }
  340. /*
  341. ** If it does not belong to a listbox...
  342. */
  343. return(GaugeClass::Draw_Me(forced));
  344. }
  345. /***********************************************************************************************
  346. * SliderClass::Peer_To_Peer -- A peer gadget was touched -- make adjustments. *
  347. * *
  348. * This routine is called when one of the peer gadgets (the scroll arrows or the slider) *
  349. * was touched in some fashion. This routine will sort out whom and why and then make *
  350. * any necessary adjustments to the list box. *
  351. * *
  352. * INPUT: flags -- The event flags that affected the peer gadget. *
  353. * key -- The key value at the time of the event. *
  354. * whom -- Which gadget is being touched. *
  355. * OUTPUT: none *
  356. * WARNINGS: none *
  357. * HISTORY: 01/16/1995 JLB : Created. *
  358. *=============================================================================================*/
  359. void SliderClass::Peer_To_Peer(unsigned flags, KeyNumType & , ControlClass & whom)
  360. {
  361. if (flags & LEFTRELEASE) {
  362. if (&whom == PlusGadget) {
  363. Step(false);
  364. }
  365. if (&whom == MinusGadget) {
  366. Step(true);
  367. }
  368. }
  369. }