Home Reference Source

cables_dev/cables_ui/src/ui/gltimeline/tloverview.js

  1. import { Events, Logger } from "cables-shared-client/index.js";
  2. import { clamp } from "cables/src/core/utils.js";
  3. import GlRect from "../gldraw/glrect.js";
  4. import { TlDragArea } from "./tldragarea.js";
  5. import Gui, { gui } from "../gui.js";
  6. import { GlTimeline } from "./gltimeline.js";
  7. import { GuiText } from "../text.js";
  8. // overview
  9. export class tlOverview extends Events
  10. {
  11. /** @type {GlRect} */
  12. #bgRect = null;
  13. /** @type {TlDragArea} */
  14. #dragBar = null;
  15. /** @type {GlRect} */
  16. #glRectCursor;
  17. /** @type {GlRect} */
  18. #glRectSelection;
  19. height = 24;
  20. #width = 222;
  21. #glTl;
  22. /** @type {GlRect[]} */
  23. #indicatorRects = [];
  24. #rulerBg;
  25. /**
  26. * @param {GlTimeline} glTl
  27. */
  28. constructor(glTl)
  29. {
  30. super();
  31. this._log = new Logger("tlOverview");
  32. this.#glTl = glTl;
  33. this.#bgRect = this.#glTl.rectsNoScroll.createRect({ "name": "scroll bg", "draggable": false, "interactive": true });
  34. this.#bgRect.setSize(this.#width, this.height);
  35. this.#rulerBg = this.#glTl.rectsNoScroll.createRect({ "name": "scroll rulesbg", "draggable": false, "interactive": false });
  36. this.#rulerBg.setPosition(0, 0, 0.1);
  37. this.#rulerBg.setSize(this.#width, this.height);
  38. this.#dragBar = new TlDragArea(glTl, this.#bgRect, this.#glTl.rectsNoScroll);
  39. this.#bgRect.on(GlRect.EVENT_POINTER_HOVER, () =>
  40. {
  41. gui.showInfo(GuiText.tlhover_scroll);
  42. });
  43. gui.on(Gui.EVENT_THEMECHANGED, () =>
  44. {
  45. this.updateColors();
  46. this.update();
  47. this.updateIndicators();
  48. }),
  49. this.#dragBar.on(TlDragArea.EVENT_MOVE, (e) =>
  50. {
  51. const f = (e.x - e.delta) / this.#width * this.#glTl.duration;
  52. this.#glTl.view.scrollTo(f);
  53. });
  54. this.#dragBar.on(TlDragArea.EVENT_RIGHT, (e) =>
  55. {
  56. this.#glTl.view.setZoomLength(e.origWidth * e.factor / this.#width * this.#glTl.duration);
  57. this.update();
  58. });
  59. // this.#glRectSelection = this.#glTl.rectsNoScroll.createRect({ "name": "scroll selection", "draggable": false, "interactive": false });
  60. // this.#glRectSelection.setColor(1, 1, 0, 0.3);
  61. // this.#glRectSelection.setPosition(0, 0, -0.09);
  62. // this.#glRectSelection.setSize(0, 0);
  63. // this.#glRectSelection.setParent(this.#bgRect);
  64. this.#glRectCursor = this.#glTl.rectsNoScroll.createRect({ "name": "cursor", "draggable": false, "interactive": false });
  65. this.#glRectCursor.setSize(1, this.height);
  66. this.#glRectCursor.setPosition(0, 0, -0.1);
  67. this.#glRectCursor.setParent(this.#bgRect);
  68. this.updateColors();
  69. this.update();
  70. }
  71. updateColors()
  72. {
  73. this.#glRectCursor.setColorArray(gui.theme.colors_timeline.cursor);
  74. this.#dragBar.setColorArray(gui.theme.colors_timeline.overview_bar || [1, 1, 1, 1]);
  75. this.#bgRect.setColorArray(gui.theme.colors_timeline.overview_background);
  76. }
  77. showAll()
  78. {
  79. this.#glTl.view.scrollTo(0);
  80. this.#glTl.view.setZoomLength(this.#glTl.duration);
  81. this.updateIndicators();
  82. }
  83. updateIndicators()
  84. {
  85. const steps = Math.floor((this.#width || 10) / 10);
  86. const stepSeconds = this.#glTl.duration / (steps - 2);
  87. this.#indicatorRects.length = Math.max(this.#indicatorRects.length, steps);
  88. const ports = gui.corePatch().getAllAnimPorts();
  89. for (let i = 0; i < this.#indicatorRects.length; i++)
  90. {
  91. let selected = false;
  92. let found = false;
  93. for (let j = 0; j < ports.length; j++)
  94. {
  95. if (ports[j].anim.hasKeyframesBetween(stepSeconds * i, stepSeconds * (i + 1)))
  96. {
  97. found = true;
  98. for (let ki = 0; ki < ports[j].anim.keys.length; ki++)
  99. {
  100. if (ports[j].anim.keys[ki].time >= stepSeconds * i && ports[j].anim.keys[ki].time < stepSeconds * (i + 1))
  101. {
  102. if (this.#glTl.isKeySelected(ports[j].anim.keys[ki]))
  103. {
  104. selected = true;
  105. break;
  106. }
  107. }
  108. }
  109. break;
  110. }
  111. }
  112. if (!this.#indicatorRects[i]) this.#indicatorRects[i] = this.#glTl.rectsNoScroll.createRect({ "interactive": false, "draggable": false, "name": "scroll indicator" + i });
  113. if (found)
  114. {
  115. const x = stepSeconds * i * this.#glTl.view.pixelPerSecond;
  116. this.#indicatorRects[i].setPosition(x, this.height / 3, -0.12);
  117. this.#indicatorRects[i].setSize(this.height / 3, this.height / 3);
  118. this.#indicatorRects[i].setShape(GlRect.SHAPE_RHOMB);
  119. if (selected)
  120. this.#indicatorRects[i].setColorArray(gui.theme.colors_timeline.key_selected);
  121. else
  122. this.#indicatorRects[i].setColor(0.5, 0.5, 0.5, 1);
  123. this.#indicatorRects[i].setParent(this.#bgRect);
  124. }
  125. else
  126. {
  127. this.#indicatorRects[i].setSize(0, 0);
  128. }
  129. }
  130. }
  131. /**
  132. * @param {number} x
  133. * @param {number} y
  134. */
  135. setPosition(x, y)
  136. {
  137. this.#bgRect.setPosition(x, y, -0.9);
  138. }
  139. /**
  140. * @param {number} w
  141. */
  142. setWidth(w)
  143. {
  144. this.#width = w;
  145. this.#bgRect.setSize(this.#width, this.height);
  146. // this.ruler.update();
  147. }
  148. update()
  149. {
  150. // const pixelVisible = (this.#glTl.view.visibleTime / this.#glTl.duration) * (this.#width / this.#glTl.view.pixelPerSecond);
  151. const pixelVisible = (this.#glTl.view.visibleTime) * this.#glTl.view.pixelPerSecond;
  152. // console.log("this.#glTl.view.offset", this.#glTl.view.offset);
  153. let x = this.#glTl.view.offset * this.#glTl.view.pixelPerSecond;
  154. let cx = Math.ceil(gui.corePatch().timer.getTime() * this.#glTl.view.pixelPerSecond);
  155. this.#dragBar.set(x, 0, -0.1, pixelVisible);
  156. this.#glRectCursor.setPosition(Math.max(0, cx - 1), 0);
  157. this.updateIndicators();
  158. const bounds = this.#glTl.getSelectedKeysBoundsTime();
  159. if (this.#glTl.getNumSelectedKeys() > 0)
  160. {
  161. // this.#glRectSelection.setPosition(bounds.min * this.#glTl.view.pixelPerSecond, 0);
  162. // this.#glRectSelection.setSize((bounds.max - bounds.min) * this.#glTl.view.pixelPerSecond + 2, this.height);
  163. }
  164. // this.ruler.update();
  165. }
  166. isHovering()
  167. {
  168. return this.#bgRect.isHovering() || this.#dragBar.isHovering;
  169. }
  170. }