GUITimeline.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  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. // TODO DOC
  11. public class GUITimeline
  12. {
  13. private const float LARGE_TICK_HEIGHT_PCT = 0.4f;
  14. private const float SMALL_TICK_HEIGHT_PCT = 0.2f;
  15. private const int PADDING = 30;
  16. private const int TEXT_PADDING = 2;
  17. private const int MIN_TICK_DISTANCE = 10;
  18. private GUICanvas canvas;
  19. private int width;
  20. private int height;
  21. private float rangeStart = 0.0f;
  22. private float rangeEnd = 60.0f;
  23. private int fps = 1;
  24. public GUITimeline(GUILayout layout, int width, int height)
  25. {
  26. canvas = new GUICanvas();
  27. layout.AddElement(canvas);
  28. SetSize(width, height);
  29. }
  30. public void SetSize(int width, int height)
  31. {
  32. this.width = width;
  33. this.height = height;
  34. canvas.SetWidth(width);
  35. canvas.SetHeight(height);
  36. Rebuild();
  37. }
  38. public void SetRange(float start, float end)
  39. {
  40. rangeStart = start;
  41. rangeEnd = end;
  42. Rebuild();
  43. }
  44. public void SetFPS(int fps)
  45. {
  46. this.fps = fps;
  47. Rebuild();
  48. }
  49. private void Rebuild()
  50. {
  51. canvas.Clear();
  52. // TODO - Calculate interval sizes based on set range, width and FPS
  53. // - Dynamically change tick heights?
  54. int drawableWidth = Math.Max(0, width - PADDING * 2);
  55. float rangeLength = rangeEnd - rangeStart;
  56. float numSmallTicksPerLarge = 5.0f;
  57. int totalNumFrames = MathEx.FloorToInt(rangeLength*fps);
  58. int numVisibleTicks = Math.Min(totalNumFrames, MathEx.FloorToInt(drawableWidth / (float) MIN_TICK_DISTANCE));
  59. float smallTickInterval = rangeLength / numVisibleTicks;
  60. float largeTickInterval = smallTickInterval * numSmallTicksPerLarge;
  61. float offsetLarge = MathEx.CeilToInt(rangeStart / largeTickInterval) * largeTickInterval - rangeStart;
  62. float offsetSmall = MathEx.CeilToInt(rangeStart / smallTickInterval) * smallTickInterval - rangeStart;
  63. int largeTickHeight = (int)(height * LARGE_TICK_HEIGHT_PCT);
  64. int smallTickHeight = (int)(height * SMALL_TICK_HEIGHT_PCT);
  65. bool drawSmallTicks = true; // TODO
  66. float t = offsetSmall;
  67. for (int i = 0; i < numVisibleTicks; i++)
  68. {
  69. float distanceToLargeTick = MathEx.CeilToInt(t / largeTickInterval) * largeTickInterval - t;
  70. if (MathEx.ApproxEquals(distanceToLargeTick, 0.0f))
  71. {
  72. int xPos = (int)((t/rangeLength)* drawableWidth) + PADDING;
  73. Vector2I start = new Vector2I(xPos, height - largeTickHeight);
  74. Vector2I end = new Vector2I(xPos, height);
  75. canvas.DrawLine(start, end, Color.LightGray);
  76. TimeSpan intervalSpan = TimeSpan.FromSeconds(largeTickInterval);
  77. TimeSpan timeSpan = TimeSpan.FromSeconds(rangeStart + t);
  78. string timeString;
  79. if(intervalSpan.Minutes > 0)
  80. timeString = timeSpan.ToString(@"m\:ss");
  81. else
  82. timeString = timeSpan.ToString(@"ss\:fff");
  83. Vector2I textBounds = GUIUtility.CalculateTextBounds(timeString, EditorBuiltin.DefaultFont,
  84. EditorStyles.DefaultFontSize);
  85. Vector2I textPosition = new Vector2I();
  86. textPosition.x = xPos - textBounds.x/2;
  87. textPosition.y = TEXT_PADDING;
  88. canvas.DrawText(timeString, textPosition, EditorBuiltin.DefaultFont, Color.LightGray,
  89. EditorStyles.DefaultFontSize);
  90. }
  91. else
  92. {
  93. if (drawSmallTicks)
  94. {
  95. int xPos = (int)((t / rangeLength) * drawableWidth) + PADDING;
  96. Vector2I start = new Vector2I(xPos, height - smallTickHeight);
  97. Vector2I end = new Vector2I(xPos, height);
  98. canvas.DrawLine(start, end, Color.LightGray);
  99. }
  100. }
  101. t += smallTickInterval;
  102. }
  103. }
  104. }
  105. /** @} */
  106. }