GUIGraphValues.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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 value at the provided position.
  69. /// </summary>
  70. /// <param name="yPos">Position to draw the text at.</param>
  71. /// <param name="value">Value to display.</param>
  72. /// <param name="above">If true the text will be displayed above the provided position, otherwise below.</param>
  73. private void DrawValue(int yPos, float value, bool above)
  74. {
  75. string valueString = value.ToString();
  76. Vector2I textBounds = GUIUtility.CalculateTextBounds(valueString, EditorBuiltin.DefaultFont,
  77. EditorStyles.DefaultFontSize);
  78. Vector2I textPosition = new Vector2I();
  79. textPosition.x = width - textBounds.x;
  80. if (above)
  81. textPosition.y = yPos - textBounds.y;
  82. else // Below
  83. {
  84. const int PADDING = 3; // So the text doesn't touch the tick
  85. textPosition.y = yPos + PADDING;
  86. }
  87. canvas.DrawText(valueString, textPosition, EditorBuiltin.DefaultFont, COLOR_TRANSPARENT_LIGHT_GRAY,
  88. EditorStyles.DefaultFontSize);
  89. }
  90. /// <summary>
  91. /// Rebuilds the internal GUI elements. Should be called whenever timeline properties change.
  92. /// </summary>
  93. public void Rebuild()
  94. {
  95. canvas.Clear();
  96. int heightOffset = height/2;
  97. float pixelsPerHeight;
  98. if (rangeEnd != rangeStart)
  99. pixelsPerHeight = height/(rangeEnd - rangeStart);
  100. else
  101. pixelsPerHeight = 0;
  102. float yOffset = rangeStart + (rangeEnd - rangeStart)*0.5f;
  103. int numTickLevels = tickHandler.NumLevels;
  104. for (int i = numTickLevels - 1; i >= 0; i--)
  105. {
  106. float[] ticks = tickHandler.GetTicks(i);
  107. float strength = tickHandler.GetLevelStrength(i);
  108. if (ticks.Length > 0)
  109. {
  110. float valuePerTick = (rangeEnd - rangeStart)/ticks.Length;
  111. for (int j = 0; j < ticks.Length; j++)
  112. {
  113. int yPos = (int) ((ticks[j] - yOffset) * pixelsPerHeight);
  114. yPos = heightOffset - yPos; // Offset and flip height (canvas Y goes down)
  115. Vector2I start = new Vector2I(0, yPos);
  116. Vector2I end = new Vector2I((int) (width*strength), yPos);
  117. Color color = COLOR_TRANSPARENT_LIGHT_GRAY;
  118. color.a *= strength;
  119. canvas.DrawLine(start, end, color);
  120. // Draw text for the highest level ticks
  121. if (i == 0)
  122. DrawValue(yPos, ticks[j], ticks[j] <= 0.0f);
  123. }
  124. }
  125. }
  126. }
  127. }
  128. /** @} */
  129. }