SliderWindow.cpp (9994B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #pragma hdrstop 30 #include "../idlib/precompiled.h" 31 32 #include "DeviceContext.h" 33 #include "Window.h" 34 #include "UserInterfaceLocal.h" 35 #include "SliderWindow.h" 36 37 /* 38 ============ 39 idSliderWindow::CommonInit 40 ============ 41 */ 42 void idSliderWindow::CommonInit() { 43 value = 0.0; 44 low = 0.0; 45 high = 100.0; 46 stepSize = 1.0; 47 thumbMat = declManager->FindMaterial("_default"); 48 buddyWin = NULL; 49 50 cvar = NULL; 51 cvar_init = false; 52 liveUpdate = true; 53 54 vertical = false; 55 scrollbar = false; 56 57 verticalFlip = false; 58 } 59 60 idSliderWindow::idSliderWindow(idUserInterfaceLocal *g) : idWindow(g) { 61 gui = g; 62 CommonInit(); 63 } 64 65 idSliderWindow::~idSliderWindow() { 66 67 } 68 69 bool idSliderWindow::ParseInternalVar(const char *_name, idTokenParser *src) { 70 if (idStr::Icmp(_name, "stepsize") == 0 || idStr::Icmp(_name, "step") == 0) { 71 stepSize = src->ParseFloat(); 72 return true; 73 } 74 if (idStr::Icmp(_name, "low") == 0) { 75 low = src->ParseFloat(); 76 return true; 77 } 78 if (idStr::Icmp(_name, "high") == 0) { 79 high = src->ParseFloat(); 80 return true; 81 } 82 if (idStr::Icmp(_name, "vertical") == 0) { 83 vertical = src->ParseBool(); 84 return true; 85 } 86 if (idStr::Icmp(_name, "verticalflip") == 0) { 87 verticalFlip = src->ParseBool(); 88 return true; 89 } 90 if (idStr::Icmp(_name, "scrollbar") == 0) { 91 scrollbar = src->ParseBool(); 92 return true; 93 } 94 if (idStr::Icmp(_name, "thumbshader") == 0) { 95 ParseString(src, thumbShader); 96 declManager->FindMaterial(thumbShader); 97 return true; 98 } 99 return idWindow::ParseInternalVar(_name, src); 100 } 101 102 idWinVar *idSliderWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) { 103 104 if (idStr::Icmp(_name, "value") == 0) { 105 return &value; 106 } 107 if (idStr::Icmp(_name, "cvar") == 0) { 108 return &cvarStr; 109 } 110 if ( idStr::Icmp( _name, "liveUpdate" ) == 0 ) { 111 return &liveUpdate; 112 } 113 if ( idStr::Icmp( _name, "cvarGroup" ) == 0 ) { 114 return &cvarGroup; 115 } 116 117 return idWindow::GetWinVarByName(_name, fixup, owner); 118 } 119 120 const char *idSliderWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) { 121 122 if (!(event->evType == SE_KEY && event->evValue2)) { 123 return ""; 124 } 125 126 int key = event->evValue; 127 128 if ( event->evValue2 && key == K_MOUSE1 ) { 129 SetCapture(this); 130 RouteMouseCoords(0.0f, 0.0f); 131 return ""; 132 } 133 134 if ( key == K_RIGHTARROW || key == K_KP_6 || ( key == K_MOUSE2 && gui->CursorY() > thumbRect.y ) ) { 135 value = value + stepSize; 136 } 137 138 if ( key == K_LEFTARROW || key == K_KP_4 || ( key == K_MOUSE2 && gui->CursorY() < thumbRect.y ) ) { 139 value = value - stepSize; 140 } 141 142 if (buddyWin) { 143 buddyWin->HandleBuddyUpdate(this); 144 } else { 145 gui->SetStateFloat( cvarStr, value ); 146 UpdateCvar( false ); 147 } 148 149 return ""; 150 } 151 152 153 void idSliderWindow::SetBuddy(idWindow *buddy) { 154 buddyWin = buddy; 155 } 156 157 void idSliderWindow::PostParse() { 158 idWindow::PostParse(); 159 value = 0.0; 160 thumbMat = declManager->FindMaterial(thumbShader); 161 thumbMat->SetSort( SS_GUI ); 162 thumbWidth = thumbMat->GetImageWidth(); 163 thumbHeight = thumbMat->GetImageHeight(); 164 //vertical = state.GetBool("vertical"); 165 //scrollbar = state.GetBool("scrollbar"); 166 flags |= (WIN_HOLDCAPTURE | WIN_CANFOCUS); 167 InitCvar(); 168 } 169 170 void idSliderWindow::InitWithDefaults(const char *_name, const idRectangle &_rect, const idVec4 &_foreColor, const idVec4 &_matColor, const char *_background, const char *thumbShader, bool _vertical, bool _scrollbar) { 171 SetInitialState(_name); 172 rect = _rect; 173 foreColor = _foreColor; 174 matColor = _matColor; 175 thumbMat = declManager->FindMaterial(thumbShader); 176 thumbMat->SetSort( SS_GUI ); 177 thumbWidth = thumbMat->GetImageWidth(); 178 thumbHeight = thumbMat->GetImageHeight(); 179 background = declManager->FindMaterial(_background); 180 background->SetSort( SS_GUI ); 181 vertical = _vertical; 182 scrollbar = _scrollbar; 183 flags |= WIN_HOLDCAPTURE; 184 } 185 186 void idSliderWindow::SetRange(float _low, float _high, float _step) { 187 low = _low; 188 high = _high; 189 stepSize = _step; 190 } 191 192 void idSliderWindow::SetValue(float _value) { 193 value = _value; 194 } 195 196 void idSliderWindow::Draw(int time, float x, float y) { 197 idVec4 color = foreColor; 198 199 if ( !cvar && !buddyWin ) { 200 return; 201 } 202 203 if ( !thumbWidth || !thumbHeight ) { 204 thumbWidth = thumbMat->GetImageWidth(); 205 thumbHeight = thumbMat->GetImageHeight(); 206 } 207 208 UpdateCvar( true ); 209 if ( value > high ) { 210 value = high; 211 } else if ( value < low ) { 212 value = low; 213 } 214 215 float range = high - low; 216 217 if ( range <= 0.0f ) { 218 return; 219 } 220 221 float thumbPos = (range) ? (value - low) / range : 0.0; 222 if (vertical) { 223 if ( verticalFlip ) { 224 thumbPos = 1.f - thumbPos; 225 } 226 thumbPos *= drawRect.h - thumbHeight; 227 thumbPos += drawRect.y; 228 thumbRect.y = thumbPos; 229 thumbRect.x = drawRect.x; 230 } else { 231 thumbPos *= drawRect.w - thumbWidth; 232 thumbPos += drawRect.x; 233 thumbRect.x = thumbPos; 234 thumbRect.y = drawRect.y; 235 } 236 thumbRect.w = thumbWidth; 237 thumbRect.h = thumbHeight; 238 239 if ( hover && !noEvents && Contains(gui->CursorX(), gui->CursorY()) ) { 240 color = hoverColor; 241 } else { 242 hover = false; 243 } 244 if ( flags & WIN_CAPTURE ) { 245 color = hoverColor; 246 hover = true; 247 } 248 249 dc->DrawMaterial(thumbRect.x, thumbRect.y, thumbRect.w, thumbRect.h, thumbMat, color); 250 if ( flags & WIN_FOCUS ) { 251 dc->DrawRect(thumbRect.x+1.0f, thumbRect.y+1.0f, thumbRect.w-2.0f, thumbRect.h-2.0f, 1.0f, color); 252 } 253 } 254 255 256 void idSliderWindow::DrawBackground(const idRectangle &_drawRect) { 257 if ( !cvar && !buddyWin ) { 258 return; 259 } 260 261 if ( high - low <= 0.0f ) { 262 return; 263 } 264 265 idRectangle r = _drawRect; 266 if (!scrollbar) { 267 if ( vertical ) { 268 r.y += thumbHeight / 2.f; 269 r.h -= thumbHeight; 270 } else { 271 r.x += thumbWidth / 2.0; 272 r.w -= thumbWidth; 273 } 274 } 275 idWindow::DrawBackground(r); 276 } 277 278 const char *idSliderWindow::RouteMouseCoords(float xd, float yd) { 279 float pct; 280 281 if (!(flags & WIN_CAPTURE)) { 282 return ""; 283 } 284 285 idRectangle r = drawRect; 286 r.x = actualX; 287 r.y = actualY; 288 r.x += thumbWidth / 2.0; 289 r.w -= thumbWidth; 290 if (vertical) { 291 r.y += thumbHeight / 2; 292 r.h -= thumbHeight; 293 if (gui->CursorY() >= r.y && gui->CursorY() <= r.Bottom()) { 294 pct = (gui->CursorY() - r.y) / r.h; 295 if ( verticalFlip ) { 296 pct = 1.f - pct; 297 } 298 value = low + (high - low) * pct; 299 } else if (gui->CursorY() < r.y) { 300 if ( verticalFlip ) { 301 value = high; 302 } else { 303 value = low; 304 } 305 } else { 306 if ( verticalFlip ) { 307 value = low; 308 } else { 309 value = high; 310 } 311 } 312 } else { 313 r.x += thumbWidth / 2; 314 r.w -= thumbWidth; 315 if (gui->CursorX() >= r.x && gui->CursorX() <= r.Right()) { 316 pct = (gui->CursorX() - r.x) / r.w; 317 value = low + (high - low) * pct; 318 } else if (gui->CursorX() < r.x) { 319 value = low; 320 } else { 321 value = high; 322 } 323 } 324 325 if (buddyWin) { 326 buddyWin->HandleBuddyUpdate(this); 327 } else { 328 gui->SetStateFloat( cvarStr, value ); 329 } 330 UpdateCvar( false ); 331 332 return ""; 333 } 334 335 336 void idSliderWindow::Activate(bool activate, idStr &act) { 337 idWindow::Activate(activate, act); 338 if ( activate ) { 339 UpdateCvar( true, true ); 340 } 341 } 342 343 /* 344 ============ 345 idSliderWindow::InitCvar 346 ============ 347 */ 348 void idSliderWindow::InitCvar( ) { 349 if ( cvarStr[0] == '\0' ) { 350 if ( !buddyWin ) { 351 common->Warning( "idSliderWindow::InitCvar: gui '%s' window '%s' has an empty cvar string", gui->GetSourceFile(), name.c_str() ); 352 } 353 cvar_init = true; 354 cvar = NULL; 355 return; 356 } 357 358 cvar = cvarSystem->Find( cvarStr ); 359 if ( !cvar ) { 360 common->Warning( "idSliderWindow::InitCvar: gui '%s' window '%s' references undefined cvar '%s'", gui->GetSourceFile(), name.c_str(), cvarStr.c_str() ); 361 cvar_init = true; 362 return; 363 } 364 } 365 366 /* 367 ============ 368 idSliderWindow::UpdateCvar 369 ============ 370 */ 371 void idSliderWindow::UpdateCvar( bool read, bool force ) { 372 if ( buddyWin || !cvar ) { 373 return; 374 } 375 if ( force || liveUpdate ) { 376 value = cvar->GetFloat(); 377 if ( value != gui->State().GetFloat( cvarStr ) ) { 378 if ( read ) { 379 gui->SetStateFloat( cvarStr, value ); 380 } else { 381 value = gui->State().GetFloat( cvarStr ); 382 cvar->SetFloat( value ); 383 } 384 } 385 } 386 } 387 388 /* 389 ============ 390 idSliderWindow::RunNamedEvent 391 ============ 392 */ 393 void idSliderWindow::RunNamedEvent( const char* eventName ) { 394 idStr event, group; 395 396 if ( !idStr::Cmpn( eventName, "cvar read ", 10 ) ) { 397 event = eventName; 398 group = event.Mid( 10, event.Length() - 10 ); 399 if ( !group.Cmp( cvarGroup ) ) { 400 UpdateCvar( true, true ); 401 } 402 } else if ( !idStr::Cmpn( eventName, "cvar write ", 11 ) ) { 403 event = eventName; 404 group = event.Mid( 11, event.Length() - 11 ); 405 if ( !group.Cmp( cvarGroup ) ) { 406 UpdateCvar( false, true ); 407 } 408 } 409 } 410