GUIGraphValues.cs 5.6 KB

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