GUIGraphValues.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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. Rebuild();
  50. }
  51. /// <summary>
  52. /// Sets the range of values to display.
  53. /// </summary>
  54. /// <param name="start">Minimum value to display.</param>
  55. /// <param name="end">Maximum value to display.</param>
  56. public void SetRange(float start, float end)
  57. {
  58. if (start > end)
  59. {
  60. float temp = start;
  61. start = end;
  62. end = temp;
  63. }
  64. rangeStart = start;
  65. rangeEnd = end;
  66. tickHandler.SetRange(rangeStart, rangeEnd, height);
  67. Rebuild();
  68. }
  69. /// <summary>
  70. /// Draws text displaying the time at the provided position.
  71. /// </summary>
  72. /// <param name="yPos">Position to draw the text at.</param>
  73. /// <param name="seconds">Time to display, in seconds.</param>
  74. /// <param name="minutes">If true the time will be displayed in minutes, otherwise in seconds.</param>
  75. /// <param name="above">If true the text will be displayed above the provided position, otherwise below.</param>
  76. private void DrawTime(int yPos, float seconds, bool minutes, bool above)
  77. {
  78. TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);
  79. string timeString;
  80. if (minutes)
  81. timeString = timeSpan.TotalMinutes.ToString("#0") + ":" + timeSpan.Seconds.ToString("D2");
  82. else
  83. timeString = timeSpan.TotalSeconds.ToString("#0.00");
  84. Vector2I textBounds = GUIUtility.CalculateTextBounds(timeString, EditorBuiltin.DefaultFont,
  85. EditorStyles.DefaultFontSize);
  86. Vector2I textPosition = new Vector2I();
  87. textPosition.x = width - textBounds.x;
  88. if (above)
  89. textPosition.y = yPos - textBounds.y;
  90. else // Below
  91. {
  92. const int PADDING = 3; // So the text doesn't touch the tick
  93. textPosition.y = yPos + PADDING;
  94. }
  95. canvas.DrawText(timeString, textPosition, EditorBuiltin.DefaultFont, COLOR_TRANSPARENT_LIGHT_GRAY,
  96. EditorStyles.DefaultFontSize);
  97. }
  98. /// <summary>
  99. /// Rebuilds the internal GUI elements. Should be called whenever timeline properties change.
  100. /// </summary>
  101. private void Rebuild()
  102. {
  103. canvas.Clear();
  104. int heightOffset = height/2;
  105. float pixelsPerHeight;
  106. if (rangeEnd != rangeStart)
  107. pixelsPerHeight = height/(rangeEnd - rangeStart);
  108. else
  109. pixelsPerHeight = 0;
  110. int numTickLevels = tickHandler.NumLevels;
  111. for (int i = numTickLevels - 1; i >= 0; i--)
  112. {
  113. float[] ticks = tickHandler.GetTicks(i);
  114. float strength = tickHandler.GetLevelStrength(i);
  115. if (ticks.Length > 0)
  116. {
  117. float valuePerTick = (rangeEnd - rangeStart)/ticks.Length;
  118. bool displayAsMinutes = TimeSpan.FromSeconds(valuePerTick).Minutes > 0;
  119. for (int j = 0; j < ticks.Length; j++)
  120. {
  121. int yPos = (int) (ticks[j]*pixelsPerHeight);
  122. yPos = heightOffset - yPos; // Offset and flip height (canvas Y goes down)
  123. Vector2I start = new Vector2I(0, yPos);
  124. Vector2I end = new Vector2I((int) (width*strength), yPos);
  125. Color color = COLOR_TRANSPARENT_LIGHT_GRAY;
  126. color.a *= strength;
  127. canvas.DrawLine(start, end, color);
  128. // Draw text for the highest level ticks
  129. if (i == 0)
  130. DrawTime(yPos, ticks[j], displayAsMinutes, ticks[j] <= 0.0f);
  131. }
  132. }
  133. }
  134. }
  135. }
  136. /** @} */
  137. }