doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ChoiceWindow.cpp
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 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 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 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 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 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 #include "../idlib/precompiled.h"
30 #pragma hdrstop
31 
32 #include "DeviceContext.h"
33 #include "Window.h"
34 #include "UserInterfaceLocal.h"
35 #include "ChoiceWindow.h"
36 
37 /*
38 ============
39 idChoiceWindow::InitVars
40 ============
41 */
43  if ( cvarStr.Length() ) {
45  if ( !cvar ) {
46  common->Warning( "idChoiceWindow::InitVars: gui '%s' window '%s' references undefined cvar '%s'", gui->GetSourceFile(), name.c_str(), cvarStr.c_str() );
47  return;
48  }
50  }
51  if ( guiStr.Length() ) {
53  }
55  updateStr.Update();
56 }
57 
58 /*
59 ============
60 idChoiceWindow::CommonInit
61 ============
62 */
64  currentChoice = 0;
65  choiceType = 0;
66  cvar = NULL;
67  liveUpdate = true;
68  choices.Clear();
69 }
70 
72  dc = d;
73  gui = g;
74  CommonInit();
75 }
76 
78  gui = g;
79  CommonInit();
80 }
81 
83 
84 }
85 
86 void idChoiceWindow::RunNamedEvent( const char* eventName ) {
87  idStr event, group;
88 
89  if ( !idStr::Cmpn( eventName, "cvar read ", 10 ) ) {
90  event = eventName;
91  group = event.Mid( 10, event.Length() - 10 );
92  if ( !group.Cmp( updateGroup ) ) {
93  UpdateVars( true, true );
94  }
95  } else if ( !idStr::Cmpn( eventName, "cvar write ", 11 ) ) {
96  event = eventName;
97  group = event.Mid( 11, event.Length() - 11 );
98  if ( !group.Cmp( updateGroup ) ) {
99  UpdateVars( false, true );
100  }
101  }
102 }
103 
104 void idChoiceWindow::UpdateVars( bool read, bool force ) {
105  if ( force || liveUpdate ) {
106  if ( cvar && cvarStr.NeedsUpdate() ) {
107  if ( read ) {
108  cvarStr.Set( cvar->GetString() );
109  } else {
110  cvar->SetString( cvarStr.c_str() );
111  }
112  }
113  if ( !read && guiStr.NeedsUpdate() ) {
114  guiStr.Set( va( "%i", currentChoice ) );
115  }
116  }
117 }
118 
119 const char *idChoiceWindow::HandleEvent(const sysEvent_t *event, bool *updateVisuals) {
120  int key;
121  bool runAction = false;
122  bool runAction2 = false;
123 
124  if ( event->evType == SE_KEY ) {
125  key = event->evValue;
126 
127  if ( key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_MOUSE1) {
128  // never affects the state, but we want to execute script handlers anyway
129  if ( !event->evValue2 ) {
131  return cmd;
132  }
133  currentChoice++;
134  if (currentChoice >= choices.Num()) {
135  currentChoice = 0;
136  }
137  runAction = true;
138  }
139 
140  if ( key == K_LEFTARROW || key == K_KP_LEFTARROW || key == K_MOUSE2) {
141  // never affects the state, but we want to execute script handlers anyway
142  if ( !event->evValue2 ) {
144  return cmd;
145  }
146  currentChoice--;
147  if (currentChoice < 0) {
148  currentChoice = choices.Num() - 1;
149  }
150  runAction = true;
151  }
152 
153  if ( !event->evValue2 ) {
154  // is a key release with no action catch
155  return "";
156  }
157 
158  } else if ( event->evType == SE_CHAR ) {
159 
160  key = event->evValue;
161 
162  int potentialChoice = -1;
163  for ( int i = 0; i < choices.Num(); i++ ) {
164  if ( toupper(key) == toupper(choices[i][0]) ) {
165  if ( i < currentChoice && potentialChoice < 0 ) {
166  potentialChoice = i;
167  } else if ( i > currentChoice ) {
168  potentialChoice = -1;
169  currentChoice = i;
170  break;
171  }
172  }
173  }
174  if ( potentialChoice >= 0 ) {
175  currentChoice = potentialChoice;
176  }
177 
178  runAction = true;
179  runAction2 = true;
180 
181  } else {
182  return "";
183  }
184 
185  if ( runAction ) {
186  RunScript( ON_ACTION );
187  }
188 
189  if ( choiceType == 0 ) {
190  cvarStr.Set( va( "%i", currentChoice ) );
191  } else if ( values.Num() ) {
193  } else {
195  }
196 
197  UpdateVars( false );
198 
199  if ( runAction2 ) {
201  }
202 
203  return cmd;
204 }
205 
207  if ( currentChoice < 0 || currentChoice >= choices.Num() ) {
208  currentChoice = 0;
209  }
210  if ( choices.Num() == 0 ) {
211  choices.Append( "No Choices Defined" );
212  }
213 }
214 
216  if ( !updateStr.Num() ) {
217  return;
218  }
219  UpdateVars( true );
220  updateStr.Update();
221  if ( choiceType == 0 ) {
222  // ChoiceType 0 stores current as an integer in either cvar or gui
223  // If both cvar and gui are defined then cvar wins, but they are both updated
224  if ( updateStr[ 0 ]->NeedsUpdate() ) {
225  currentChoice = atoi( updateStr[ 0 ]->c_str() );
226  }
227  ValidateChoice();
228  } else {
229  // ChoiceType 1 stores current as a cvar string
230  int c = ( values.Num() ) ? values.Num() : choices.Num();
231  int i;
232  for ( i = 0; i < c; i++ ) {
233  if ( idStr::Icmp( cvarStr.c_str(), ( values.Num() ) ? values[i] : choices[i] ) == 0 ) {
234  break;
235  }
236  }
237  if (i == c) {
238  i = 0;
239  }
240  currentChoice = i;
241  ValidateChoice();
242  }
243 }
244 
245 bool idChoiceWindow::ParseInternalVar(const char *_name, idParser *src) {
246  if (idStr::Icmp(_name, "choicetype") == 0) {
247  choiceType = src->ParseInt();
248  return true;
249  }
250  if (idStr::Icmp(_name, "currentchoice") == 0) {
251  currentChoice = src->ParseInt();
252  return true;
253  }
254  return idWindow::ParseInternalVar(_name, src);
255 }
256 
257 
258 idWinVar *idChoiceWindow::GetWinVarByName(const char *_name, bool fixup, drawWin_t** owner) {
259  if ( idStr::Icmp( _name, "choices" ) == 0 ) {
260  return &choicesStr;
261  }
262  if ( idStr::Icmp( _name, "values" ) == 0 ) {
263  return &choiceVals;
264  }
265  if ( idStr::Icmp( _name, "cvar" ) == 0 ) {
266  return &cvarStr;
267  }
268  if ( idStr::Icmp( _name, "gui" ) == 0 ) {
269  return &guiStr;
270  }
271  if ( idStr::Icmp( _name, "liveUpdate" ) == 0 ) {
272  return &liveUpdate;
273  }
274  if ( idStr::Icmp( _name, "updateGroup" ) == 0 ) {
275  return &updateGroup;
276  }
277 
278  return idWindow::GetWinVarByName(_name, fixup, owner);
279 }
280 
281 // update the lists whenever the WinVar have changed
283  idToken token;
284  idStr str2, str3;
285  idLexer src;
286 
287  if ( latchedChoices.Icmp( choicesStr ) ) {
288  choices.Clear();
289  src.FreeSource();
291  src.LoadMemory( choicesStr, choicesStr.Length(), "<ChoiceList>" );
292  if ( src.IsLoaded() ) {
293  while( src.ReadToken( &token ) ) {
294  if ( token == ";" ) {
295  if ( str2.Length() ) {
297  str2 = common->GetLanguageDict()->GetString( str2 );
298  choices.Append(str2);
299  str2 = "";
300  }
301  continue;
302  }
303  str2 += token;
304  str2 += " ";
305  }
306  if ( str2.Length() ) {
308  choices.Append( str2 );
309  }
310  }
312  }
313  if ( choiceVals.Length() && latchedVals.Icmp( choiceVals ) ) {
314  values.Clear();
315  src.FreeSource();
317  src.LoadMemory( choiceVals, choiceVals.Length(), "<ChoiceVals>" );
318  str2 = "";
319  bool negNum = false;
320  if ( src.IsLoaded() ) {
321  while( src.ReadToken( &token ) ) {
322  if (token == "-") {
323  negNum = true;
324  continue;
325  }
326  if (token == ";") {
327  if (str2.Length()) {
329  values.Append( str2 );
330  str2 = "";
331  }
332  continue;
333  }
334  if ( negNum ) {
335  str2 += "-";
336  negNum = false;
337  }
338  str2 += token;
339  str2 += " ";
340  }
341  if ( str2.Length() ) {
343  values.Append( str2 );
344  }
345  }
346  if ( choices.Num() != values.Num() ) {
347  common->Warning( "idChoiceWindow:: gui '%s' window '%s' has value count unequal to choices count", gui->GetSourceFile(), name.c_str());
348  }
350  }
351 }
352 
356 
357  InitVars();
358  UpdateChoice();
359  UpdateVars(false);
360 
361  flags |= WIN_CANFOCUS;
362 }
363 
364 void idChoiceWindow::Draw(int time, float x, float y) {
366 
368  UpdateChoice();
369 
370  // FIXME: It'd be really cool if textAlign worked, but a lot of the guis have it set wrong because it used to not work
371  textAlign = 0;
372 
373  if ( textShadow ) {
374  idStr shadowText = choices[currentChoice];
375  idRectangle shadowRect = textRect;
376 
377  shadowText.RemoveColors();
378  shadowRect.x += textShadow;
379  shadowRect.y += textShadow;
380 
381  dc->DrawText( shadowText, textScale, textAlign, colorBlack, shadowRect, false, -1 );
382  }
383 
384  if ( hover && !noEvents && Contains(gui->CursorX(), gui->CursorY()) ) {
385  color = hoverColor;
386  } else {
387  hover = false;
388  }
389  if ( flags & WIN_FOCUS ) {
390  color = hoverColor;
391  }
392 
393  dc->DrawText( choices[currentChoice], textScale, textAlign, color, textRect, false, -1 );
394 }
395 
396 void idChoiceWindow::Activate( bool activate, idStr &act ) {
397  idWindow::Activate( activate, act );
398  if ( activate ) {
399  // sets the gui state based on the current choice the window contains
400  UpdateChoice();
401  }
402 }
GLubyte g
Definition: glext.h:4662
byte color[4]
Definition: MegaTexture.cpp:54
idWinStr guiStr
Definition: ChoiceWindow.h:73
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:2868
virtual void Draw(int time, float x, float y)
idWinStr updateGroup
Definition: ChoiceWindow.h:79
idWinFloat textScale
Definition: Window.h:405
int Length()
Definition: Winvar.h:192
int Cmp(const char *text) const
Definition: Str.h:652
idChoiceWindow(idUserInterfaceLocal *gui)
idCVarSystem * cvarSystem
Definition: CVarSystem.cpp:487
bool Contains(float x, float y)
Definition: Window.cpp:681
void Update(void)
Definition: Winvar.cpp:72
signed char textShadow
Definition: Window.h:391
idWinStr choiceVals
Definition: ChoiceWindow.h:69
virtual void virtual void virtual const idLangDict * GetLanguageDict(void)=0
void UpdateVars(bool read, bool force=false)
void FreeSource(void)
Definition: Lexer.cpp:1676
void RunNamedEvent(const char *eventName)
unsigned int flags
Definition: Window.h:371
int Length(void) const
Definition: Str.h:702
idWinBool noEvents
Definition: Window.h:398
virtual bool ParseInternalVar(const char *name, idParser *src)
Definition: Window.cpp:1915
void StripTrailingWhitespace(void)
Definition: Str.cpp:648
GLenum GLint GLint y
Definition: glext.h:2849
signed char textAlign
Definition: Window.h:394
const int WIN_FOCUS
Definition: Window.h:44
idStrList choices
Definition: ChoiceWindow.h:70
Definition: Token.h:71
void SetFlags(int flags)
Definition: Lexer.h:298
idDeviceContext * dc
Definition: Window.h:425
GLuint src
Definition: glext.h:5390
GLenum GLint x
Definition: glext.h:2849
int i
Definition: process.py:33
int Cmpn(const char *text, int n) const
Definition: Str.h:657
int Icmp(const char *text) const
Definition: Str.h:667
virtual void Activate(bool activate, idStr &act)
virtual const char * HandleEvent(const sysEvent_t *event, bool *updateVisuals)
virtual idCVar * Find(const char *name)=0
Definition: Lexer.h:137
virtual void Activate(bool activate, idStr &act)
Definition: Window.cpp:481
void SetString(const char *value)
Definition: CVarSystem.h:146
virtual void PostParse()
Definition: Window.cpp:1709
int ParseInt(void)
Definition: Parser.cpp:2775
int DrawText(const char *text, float textScale, int textAlign, idVec4 color, idRectangle rectDraw, bool wrap, int cursor=-1, bool calcOnly=false, idList< int > *breaks=NULL, int limit=0)
const GLubyte * c
Definition: glext.h:4677
Definition: Vector.h:808
float y
Definition: Rectangle.h:37
idCommon * common
Definition: Common.cpp:206
void UpdateChoicesAndVals(void)
idCVar * cvar
Definition: ChoiceWindow.h:75
#define NULL
Definition: Lib.h:88
int evValue2
Definition: sys_public.h:218
idWinStr choicesStr
Definition: ChoiceWindow.h:67
virtual float CursorY()
const char * GetSourceFile(void) const
idWinVec4 foreColor
Definition: Window.h:402
const int WIN_CANFOCUS
Definition: Window.h:50
const char * GetString(const char *str) const
Definition: LangDict.cpp:148
virtual void PostParse()
idStr latchedChoices
Definition: ChoiceWindow.h:66
idWinStr cvarStr
Definition: ChoiceWindow.h:74
idStr & RemoveColors(void)
Definition: Str.h:849
int LoadMemory(const char *ptr, int length, const char *name, int startLine=1)
Definition: Lexer.cpp:1646
sysEventType_t evType
Definition: sys_public.h:216
idStr cmd
Definition: Window.h:316
float x
Definition: Rectangle.h:36
idMultiWinVar updateStr
Definition: ChoiceWindow.h:76
virtual ~idChoiceWindow()
const char * GetString(void) const
Definition: CVarSystem.h:141
int Append(const type &obj)
Definition: List.h:646
const char * Mid(int start, int len, idStr &result) const
Definition: Str.cpp:603
idUserInterfaceLocal * gui
Definition: Window.h:427
int Num(void) const
Definition: List.h:265
const GLcharARB * name
Definition: glext.h:3629
Definition: Str.h:116
virtual const char * c_str() const
Definition: Winvar.h:204
void SetGuiInfo(idDict *dict)
Definition: Winvar.cpp:78
bool RunScript(int n)
Definition: Window.cpp:2690
bool hover
Definition: Window.h:423
int IsLoaded(void)
Definition: Lexer.h:158
virtual bool ParseInternalVar(const char *name, idParser *src)
char * va(const char *fmt,...)
Definition: Str.cpp:1568
virtual void Set(const char *val)
Definition: Winvar.h:208
idVec4 colorBlack
Definition: Lib.cpp:115
virtual void virtual void Warning(const char *fmt,...) id_attribute((format(printf
virtual float CursorX()
virtual idWinVar * GetWinVarByName(const char *_name, bool winLookup=false, drawWin_t **owner=NULL)
Definition: Window.cpp:1776
int ReadToken(idToken *token)
Definition: Lexer.cpp:820
virtual idWinVar * GetWinVarByName(const char *_name, bool winLookup=false, drawWin_t **owner=NULL)
idRectangle textRect
Definition: Window.h:413
idWinVec4 hoverColor
Definition: Window.h:403
bool NeedsUpdate()
Definition: Winvar.h:69
void Clear(void)
Definition: List.h:184
idWinBool liveUpdate
Definition: ChoiceWindow.h:78