00001 using System;
00002 using System.Collections.Generic;
00003 using System.Text;
00004
00005 using Microsoft.Xna.Framework;
00006 using Microsoft.Xna.Framework.Graphics;
00007
00008 using NewGamePhysics.StateManager;
00009 using NewGamePhysics.Utilities;
00010 using NewGamePhysics.GraphicalElements;
00011
00012 namespace NewGamePhysics.GraphicalElements
00013 {
00020 public class ValueIndicator : GraphicalElementBase
00021 {
00025 private double value;
00026
00030 private string format;
00031
00036 private string valueAsString = String.Empty;
00037
00041 private DateTime valueUpdate;
00042
00046 private double minimumValue;
00047
00051 private double maximumValue;
00052
00057 private bool haveZero;
00058
00064 private double lowValue;
00065
00071 private double highValue;
00072
00076 private Vector2 position;
00077
00081 public const float Width = 200.0f;
00082
00086 public const float Height = 40.0f;
00087
00091 private string label;
00092
00096 private Color drawColor;
00097
00101 private bool lowHighColoring;
00102
00107 private Color barColor;
00108
00115 private Color[] barColors;
00116
00121 private double updateInterval = 250.0;
00122
00126 private Texture2D backgroundTexture;
00127
00131 private Texture2D whiteTexture;
00132
00136 private SpriteFont spriteFont;
00137
00144 public ValueIndicator(
00145 ScreenManager manager,
00146 string label,
00147 string format)
00148 : this(manager, label, format, 0.0, 0.0)
00149 {
00150 }
00151
00160 public ValueIndicator(
00161 ScreenManager manager,
00162 string label,
00163 string format,
00164 double minimum,
00165 double maximum) : base(manager)
00166 {
00167
00168 this.label = label;
00169 this.format = format;
00170
00171
00172 this.minimumValue = minimum;
00173 this.maximumValue = maximum;
00174 double delta = 0.1 * (maximum - minimum);
00175 this.lowValue = minimum + delta;
00176 this.highValue = maximum - delta;
00177
00178
00179 this.haveZero = ((this.minimumValue < 0.0) && (this.maximumValue > 0.0));
00180
00181
00182 this.position = new Vector2();
00183
00184
00185 this.drawColor = new Color(180, 255, 180);
00186
00187
00188 this.barColors = new Color[3];
00189
00190 this.barColors[0] = new Color(255, 0, 0);
00191
00192 this.barColors[1] = new Color(255, 255, 0);
00193
00194 this.barColors[2] = new Color(0, 255, 0);
00195
00196
00197 this.backgroundTexture = ScreenManager.Game.Content.Load<Texture2D>(@"Sprites\value_gauge");
00198
00199
00200 this.whiteTexture = TextureHelpers.Create(ScreenManager.GraphicsDevice, Color.White);
00201
00202
00203 this.SetValue(0.0);
00204
00205
00206 this.spriteFont = ScreenManager.Fonts["small"];
00207 }
00208
00209 #region properties
00210
00214 public double MinimumValue
00215 {
00216 get
00217 {
00218 return this.minimumValue;
00219 }
00220
00221 set
00222 {
00223 this.minimumValue = value;
00224
00225
00226 if (this.lowValue < value)
00227 {
00228 this.lowValue = value;
00229 }
00230
00231
00232 this.haveZero = ((this.minimumValue < 0.0) && (this.maximumValue > 0.0));
00233 }
00234 }
00235
00239 public double MaximumValue
00240 {
00241 get
00242 {
00243 return this.maximumValue;
00244 }
00245
00246 set
00247 {
00248 this.maximumValue = value;
00249
00250
00251 if (this.highValue > value)
00252 {
00253 this.highValue = value;
00254 }
00255
00256
00257 this.haveZero = ((this.minimumValue < 0.0) && (this.maximumValue > 0.0));
00258 }
00259 }
00260
00265 public double LowValue
00266 {
00267 get { return this.lowValue; }
00268
00269 set
00270 {
00271 if (value < this.minimumValue)
00272 {
00273 throw new ArgumentOutOfRangeException("value");
00274 }
00275
00276 this.lowValue = value;
00277 }
00278 }
00279
00284 public double HighValue
00285 {
00286 get { return this.highValue; }
00287
00288 set
00289 {
00290 if (value > this.maximumValue)
00291 {
00292 throw new ArgumentOutOfRangeException("value");
00293 }
00294
00295 this.highValue = value;
00296 }
00297 }
00298
00302 public bool LowHighColoring
00303 {
00304 get { return this.lowHighColoring; }
00305 set { this.lowHighColoring = value; }
00306 }
00307
00312 public double UpdateInterval
00313 {
00314 get { return this.updateInterval; }
00315 set { this.updateInterval = value; }
00316 }
00317
00318 #endregion
00319
00325 public void SetValue(double value)
00326 {
00327
00328 this.MinimumValue = Math.Min(this.minimumValue, Autorange.GetSnapValue(value, false));
00329 this.MaximumValue = Math.Max(this.maximumValue, Autorange.GetSnapValue(value, true));
00330
00331
00332 double delta = 0.1 * (this.maximumValue - this.minimumValue);
00333 this.LowValue = this.minimumValue + delta;
00334 this.HighValue = this.maximumValue - delta;
00335
00336
00337 this.value = value;
00338 UpdateBarColor();
00339 }
00340
00347 public void SetValueInRange(double value)
00348 {
00349
00350 if (value < minimumValue)
00351 {
00352 this.value = this.minimumValue;
00353 }
00354 else if (value > maximumValue)
00355 {
00356 this.value = this.maximumValue;
00357 }
00358 else
00359 {
00360 this.value = value;
00361 }
00362
00363 UpdateBarColor();
00364 }
00365
00370 public void SetMinimum(double value)
00371 {
00372 this.minimumValue = value;
00373 }
00374
00379 public void SetMaximum(double value)
00380 {
00381 this.maximumValue = value;
00382 }
00383
00388 public void SetPosition(Vector2 position)
00389 {
00390 this.position.X = position.X;
00391 this.position.Y = position.Y;
00392 }
00393
00399 public void Draw(GameTime gameTime)
00400 {
00401 float outerHeight = Height;
00402 float innerHeightStep = 12.0f;
00403 float innerHeight = 3.0f * innerHeightStep;
00404
00405 float outerWidth = Width;
00406 float innerWidth = Width - 4.0f;
00407 float rowOffsetX = 2.0f;
00408 float row1OffsetY = 2.0f;
00409 float row2OffsetY = 2.0f + innerHeightStep;
00410 float row3OffsetY = 2.0f + 2.0f*innerHeightStep;
00411 float rowHeight = 10.0f;
00412 float valueOffset = innerWidth * (float)((this.value - this.minimumValue) / (this.maximumValue - this.minimumValue));
00413 float zeroOffset = innerWidth * (float)((0.0 - this.minimumValue) / (this.maximumValue - this.minimumValue));
00414
00415 Rectangle destination;
00416
00417
00418 DateTime currentDate = DateTime.Now;
00419 TimeSpan elapsedSpan = new TimeSpan(currentDate.Ticks - valueUpdate.Ticks);
00420 if (elapsedSpan.TotalMilliseconds > this.updateInterval)
00421 {
00422 valueAsString = String.Format(
00423 this.format,
00424 this.value);
00425 valueUpdate = currentDate;
00426 }
00427
00428
00429 destination = new Rectangle((int)this.position.X, (int)this.position.Y, (int)outerWidth, (int)outerHeight);
00430 SpriteBatch.Begin();
00431 SpriteBatch.Draw(this.backgroundTexture, destination, Color.White);
00432 SpriteBatch.End();
00433
00434
00435 Vector2 textSize = spriteFont.MeasureString(valueAsString);
00436 SpriteBatch.Begin();
00437 SpriteBatch.DrawString(
00438 spriteFont,
00439 valueAsString,
00440 new Vector2(this.position.X + rowOffsetX, this.position.Y + row1OffsetY),
00441 this.drawColor, 0, new Vector2(), 1.0f,
00442 SpriteEffects.None, 0);
00443 SpriteBatch.End();
00444
00445
00446 if ((this.haveZero) && (valueOffset < zeroOffset))
00447 {
00448 destination = new Rectangle((int)(this.position.X + rowOffsetX + valueOffset), (int)(this.position.Y + row2OffsetY) + 1, (int)(zeroOffset - valueOffset), (int)rowHeight - 1);
00449 }
00450 else
00451 {
00452 destination = new Rectangle((int)(this.position.X + rowOffsetX + zeroOffset), (int)(this.position.Y + row2OffsetY) + 1, (int)(valueOffset - zeroOffset), (int)rowHeight - 1);
00453 }
00454 SpriteBatch.Begin();
00455 SpriteBatch.Draw(this.whiteTexture, destination, this.barColor);
00456 SpriteBatch.End();
00457
00458
00459 PrimitiveBatch.Begin(PrimitiveType.LineList);
00460 Vector2 offset = new Vector2(rowOffsetX, row2OffsetY);
00461
00462
00463 if (this.haveZero)
00464 {
00465 Color lineColor = new Color(this.drawColor, 128);
00466 PrimitiveBatch.AddVertex(this.position + offset + new Vector2(zeroOffset, 0.0f), lineColor);
00467 PrimitiveBatch.AddVertex(this.position + offset + new Vector2(zeroOffset, rowHeight), lineColor);
00468 }
00469
00470
00471 PrimitiveBatch.AddVertex(this.position + offset + new Vector2(valueOffset, 0.0f), this.drawColor);
00472 PrimitiveBatch.AddVertex(this.position + offset + new Vector2(valueOffset, rowHeight), this.drawColor);
00473
00474 PrimitiveBatch.End();
00475
00476
00477 if (!String.IsNullOrEmpty(this.label))
00478 {
00479 textSize = spriteFont.MeasureString(this.label);
00480 float textOffset = (innerWidth - textSize.X) * 0.5f;
00481 SpriteBatch.Begin();
00482 SpriteBatch.DrawString(
00483 spriteFont,
00484 this.label,
00485 new Vector2(this.position.X + rowOffsetX + textOffset, this.position.Y + row3OffsetY),
00486 Color.Black, 0, new Vector2(), 1.0f,
00487 SpriteEffects.None, 0);
00488 SpriteBatch.End();
00489 }
00490 }
00491
00495 private void UpdateBarColor()
00496 {
00497 if (this.lowHighColoring &&
00498 ((this.value == this.minimumValue) || (this.value == this.maximumValue)))
00499 {
00500
00501 this.barColor = barColors[0];
00502 }
00503 else if (this.lowHighColoring &&
00504 ((this.value < this.lowValue) || (this.value > this.highValue)))
00505 {
00506
00507 this.barColor = barColors[1];
00508 }
00509 else
00510 {
00511
00512 this.barColor = barColors[2];
00513 }
00514 }
00515 }
00516 }