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