TreeItem.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. module INSPECTOR {
  2. export class TreeItem extends BasicElement {
  3. // Reference to the tab
  4. private _tab: Tab;
  5. // The object this item is linked to (should be a primitive or a canvas) TODO should be superclass of all primitives
  6. private _adapter: Adapter;
  7. private _tools: Array<AbstractTreeTool>;
  8. public children: Array<TreeItem> = [];
  9. // Div element that contains all children of this node.
  10. private _lineContent: HTMLElement;
  11. constructor(tab: Tab, obj: Adapter) {
  12. super();
  13. this._tab = tab;
  14. this._adapter = obj;
  15. this._tools = this._adapter.getTools();
  16. this._build();
  17. }
  18. /** Returns the item ID == its adapter ID */
  19. public get id(): string {
  20. return this._adapter.id();
  21. }
  22. /** Add the given item as a child of this one */
  23. public add(child: TreeItem) {
  24. this.children.push(child);
  25. this.update();
  26. }
  27. /**
  28. * Returns the original adapter
  29. */
  30. public get adapter(): Adapter {
  31. return this._adapter;
  32. }
  33. /**
  34. * Function used to compare this item to another tree item.
  35. * Returns the alphabetical sort of the adapter ID
  36. */
  37. public compareTo(item: TreeItem): number {
  38. let str1 = this.id;
  39. let str2 = item.id;
  40. return str1.localeCompare(str2, [], { numeric: true });
  41. }
  42. /** Returns true if the given obj correspond to the adapter linked to this tree item */
  43. public correspondsTo(obj: any): boolean {
  44. return this._adapter.correspondsTo(obj);
  45. }
  46. /** hide all children of this item */
  47. public fold() {
  48. // Do nothing id no children
  49. if (this.children.length > 0) {
  50. for (let elem of this.children) {
  51. elem.toHtml().style.display = 'none';
  52. }
  53. this._div.classList.add('folded');
  54. this._div.classList.remove('unfolded');
  55. }
  56. }
  57. /** Show all children of this item */
  58. public unfold() {
  59. // Do nothing id no children
  60. if (this.children.length > 0) {
  61. for (let elem of this.children) {
  62. elem.toHtml().style.display = 'block';
  63. }
  64. this._div.classList.add('unfolded');
  65. this._div.classList.remove('folded');
  66. }
  67. }
  68. /** Build the HTML of this item */
  69. protected _build() {
  70. /**
  71. * Hide the debug objects :
  72. * - Axis : xline, yline, zline
  73. * */
  74. let adapterId = this._adapter.id();
  75. if (adapterId == "xline"
  76. || adapterId == "yline"
  77. || adapterId == "zline") {
  78. this._div.className = "line_invisible";
  79. }
  80. else this._div.className = 'line';
  81. // special class for transform node ONLY
  82. if (this.adapter instanceof MeshAdapter) {
  83. let obj = this.adapter.object;
  84. if (obj instanceof BABYLON.TransformNode && !(obj instanceof BABYLON.AbstractMesh)) {
  85. this._div.className += ' transformNode';
  86. }
  87. }
  88. for (let tool of this._tools) {
  89. this._div.appendChild(tool.toHtml());
  90. }
  91. // Id
  92. let text = Inspector.DOCUMENT.createElement('span');
  93. text.textContent = this._adapter.id();
  94. this._div.appendChild(text);
  95. // Type
  96. let type = Inspector.DOCUMENT.createElement('span');
  97. type.className = 'property-type';
  98. if (this._adapter.type() !== 'type_not_defined') {
  99. type.textContent = ' - ' + this._adapter.type();
  100. }
  101. this._div.appendChild(type);
  102. this._lineContent = Helpers.CreateDiv('line-content', this._div);
  103. this._addEvent();
  104. }
  105. /**
  106. * Returns one HTML element (.details) containing all details of this primitive
  107. */
  108. public getDetails(): Array<PropertyLine> {
  109. return this._adapter.getProperties();
  110. }
  111. public update() {
  112. // Clean division holding all children
  113. Helpers.CleanDiv(this._lineContent);
  114. for (let child of this.children) {
  115. let elem = child.toHtml();
  116. this._lineContent.appendChild(elem);
  117. }
  118. if (this.children.length > 0) {
  119. // Check if folded or not
  120. if (!this._div.classList.contains('folded') && !this._div.classList.contains('unfolded')) {
  121. this._div.classList.add('folded');
  122. }
  123. }
  124. this.fold();
  125. }
  126. /**
  127. * Add an event listener on the item :
  128. * - one click display details
  129. */
  130. protected _addEvent() {
  131. this._div.addEventListener('click', (e) => {
  132. this._tab.select(this);
  133. // Fold/unfold the tree
  134. if (this._isFolded()) {
  135. this.unfold();
  136. } else {
  137. this.fold();
  138. }
  139. e.stopPropagation();
  140. });
  141. }
  142. /** Returns true if the node is folded, false otherwise */
  143. private _isFolded(): boolean {
  144. return !this._div.classList.contains('unfolded');
  145. }
  146. /** Set this item as active (background lighter) in the tree panel */
  147. public active(b: boolean) {
  148. this._div.classList.remove('active');
  149. for (let child of this.children) {
  150. child.active(false);
  151. }
  152. if (b) {
  153. this._div.classList.add('active');
  154. }
  155. }
  156. public getDiv() {
  157. return this._div;
  158. }
  159. }
  160. }