GUIGraphValues.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using BansheeEngine;
  5. namespace BansheeEditor
  6. {
  7. /** @addtogroup AnimationEditor
  8. * @{
  9. */
  10. /// <summary>
  11. /// Renders a vertical value display that may be used as a side-bar for a graph display. User can set the range of the
  12. /// values to display, as well as its physical dimensions.
  13. /// </summary>
  14. internal class GUIGraphValues
  15. {
  16. private static readonly Color COLOR_TRANSPARENT_LIGHT_GRAY =
  17. new Color(200.0f / 255.0f, 200.0f / 255.0f, 200.0f / 255.0f, 0.5f);
  18. private GUIGraphTicks tickHandler;
  19. private GUICanvas canvas;
  20. private int width = 20;
  21. private int height = 20;
  22. private float rangeStart = -1.0f;
  23. private float rangeEnd = 1.0f;
  24. /// <summary>
  25. /// Constructs a new value display and adds it to the specified layout.
  26. /// </summary>
  27. /// <param name="layout">Layout to add the GUI element to.</param>
  28. /// <param name="width">Width of the timeline in pixels.</param>
  29. /// <param name="height">Height of the timeline in pixels.</param>
  30. public GUIGraphValues(GUILayout layout, int width, int height)
  31. {
  32. canvas = new GUICanvas();
  33. layout.AddElement(canvas);
  34. tickHandler = new GUIGraphTicks();
  35. SetSize(width, height);
  36. }
  37. /// <summary>
  38. /// Sets the physical size onto which to draw the value display.
  39. /// </summary>
  40. /// <param name="width">Width in pixels.</param>
  41. /// <param name="height">Height in pixels.</param>
  42. public void SetSize(int width, int height)
  43. {
  44. this.width = width;
  45. this.height = height;
  46. canvas.SetWidth(width);
  47. canvas.SetHeight(height);
  48. tickHandler.SetRange(rangeStart, rangeEnd, height);
  49. }
  50. /// <summary>
  51. /// Sets the range of values to display.
  52. /// </summary>
  53. /// <param name="start">Minimum value to display.</param>
  54. /// <param name="end">Maximum value to display.</param>
  55. public void SetRange(float start, float end)
  56. {
  57. if (start > end)
  58. {
  59. float temp = start;
  60. start = end;
  61. end = temp;
  62. }
  63. rangeStart = start;
  64. rangeEnd = end;
  65. tickHandler.SetRange(rangeStart, rangeEnd, height);
  66. }
  67. /// <summary>
  68. /// Draws text displaying the time at the provided position.
  69. /// </summary>
  70. /// <param name="yPos">Position to draw the text at.</param>
  71. /// <param name="seconds">Time to display, in seconds.</param>
  72. /// <param name="minutes">If true the time will be displayed in minutes, otherwise in seconds.</param>
  73. /// <param name="above">If true the text will be displayed above the provided position, otherwise below.</param>
  74. private void DrawTime(int yPos, float seconds, bool minutes, bool above)
  75. {
  76. TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);
  77. string timeString;
  78. if (minutes)
  79. timeString = timeSpan.TotalMinutes.ToString("#0") + ":" + timeSpan.Seconds.ToString("D2");
  80. else
  81. timeString = timeSpan.TotalSeconds.ToString("#0.00");
  82. Vector2I textBounds = GUIUtility.CalculateTextBounds(timeString, EditorBuiltin.DefaultFont,
  83. EditorStyles.DefaultFontSize);
  84. Vector2I textPosition = new Vector2I();
  85. textPosition.x = width - textBounds.x;
  86. if (above)
  87. textPosition.y = yPos - textBounds.y;
  88. else // Below
  89. {
  90. const int PADDING = 3; // So the text doesn't touch the tick
  91. textPosition.y = yPos + PADDING;
  92. }
  93. canvas.DrawText(timeString, textPosition, EditorBuiltin.DefaultFont, COLOR_TRANSPARENT_LIGHT_GRAY,
  94. EditorStyles.DefaultFontSize);
  95. }
  96. /// <summary>
  97. /// Rebuilds the internal GUI elements. Should be called whenever timeline properties change.
  98. /// </summary>
  99. public void Rebuild()
  100. {
  101. canvas.Clear();
  102. int heightOffset = height/2;
  103. float pixelsPerHeight;
  104. if (rangeEnd != rangeStart)
  105. pixelsPerHeight = height/(rangeEnd - rangeStart);
  106. else
  107. pixelsPerHeight = 0;
  108. int numTickLevels = tickHandler.NumLevels;
  109. for (int i = numTickLevels - 1; i >= 0; i--)
  110. {
  111. float[] ticks = tickHandler.GetTicks(i);
  112. float strength = tickHandler.GetLevelStrength(i);
  113. if (ticks.Length > 0)
  114. {
  115. float valuePerTick = (rangeEnd - rangeStart)/ticks.Length;
  116. bool displayAsMinutes = TimeSpan.FromSeconds(valuePerTick).Minutes > 0;
  117. for (int j = 0; j < ticks.Length; j++)
  118. {
  119. int yPos = (int) (ticks[j]*pixelsPerHeight);
  120. yPos = heightOffset - yPos; // Offset and flip height (canvas Y goes down)
  121. Vector2I start = new Vector2I(0, yPos);
  122. Vector2I end = new Vector2I((int) (width*strength), yPos);
  123. Color color = COLOR_TRANSPARENT_LIGHT_GRAY;
  124. color.a *= strength;
  125. canvas.DrawLine(start, end, color);
  126. // Draw text for the highest level ticks
  127. if (i == 0)
  128. DrawTime(yPos, ticks[j], displayAsMinutes, ticks[j] <= 0.0f);
  129. }
  130. }
  131. }
  132. }
  133. }
  134. /** @} */
  135. }