container.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /// <reference path="../../../dist/preview release/babylon.d.ts"/>
  2. module BABYLON.GUI {
  3. export class Container extends Control {
  4. protected _children = new Array<Control>();
  5. protected _measureForChildren = Measure.Empty();
  6. protected _background: string;
  7. protected _adaptWidthToChildren = false;
  8. protected _adaptHeightToChildren = false;
  9. public get adaptHeightToChildren(): boolean {
  10. return this._adaptHeightToChildren;
  11. }
  12. public set adaptHeightToChildren(value: boolean) {
  13. if (this._adaptHeightToChildren === value) {
  14. return;
  15. }
  16. this._adaptHeightToChildren = value;
  17. if (value) {
  18. this.height = "100%";
  19. }
  20. this._markAsDirty();
  21. }
  22. public get adaptWidthToChildren(): boolean {
  23. return this._adaptWidthToChildren;
  24. }
  25. public set adaptWidthToChildren(value: boolean) {
  26. if (this._adaptWidthToChildren === value) {
  27. return;
  28. }
  29. this._adaptWidthToChildren = value;
  30. if (value) {
  31. this.width = "100%";
  32. }
  33. this._markAsDirty();
  34. }
  35. public get background(): string {
  36. return this._background;
  37. }
  38. public set background(value: string) {
  39. if (this._background === value) {
  40. return;
  41. }
  42. this._background = value;
  43. this._markAsDirty();
  44. }
  45. public get children(): Control[] {
  46. return this._children;
  47. }
  48. constructor(public name?: string) {
  49. super(name);
  50. }
  51. protected _getTypeName(): string {
  52. return "Container";
  53. }
  54. public getChildByName(name: string): Nullable<Control> {
  55. for (var child of this._children) {
  56. if (child.name === name) {
  57. return child;
  58. }
  59. }
  60. return null;
  61. }
  62. public getChildByType(name: string, type: string): Nullable<Control> {
  63. for (var child of this._children) {
  64. if (child.typeName === type) {
  65. return child;
  66. }
  67. }
  68. return null;
  69. }
  70. public containsControl(control: Control): boolean {
  71. return this._children.indexOf(control) !== -1;
  72. }
  73. public addControl(control: Control): Container {
  74. var index = this._children.indexOf(control);
  75. if (index !== -1) {
  76. return this;
  77. }
  78. control._link(this, this._host);
  79. control._markAllAsDirty();
  80. this._reOrderControl(control);
  81. this._markAsDirty();
  82. return this;
  83. }
  84. public removeControl(control: Control): Container {
  85. var index = this._children.indexOf(control);
  86. if (index !== -1) {
  87. this._children.splice(index, 1);
  88. control.parent = null;
  89. }
  90. control.linkWithMesh(null);
  91. this._markAsDirty();
  92. return this;
  93. }
  94. public _reOrderControl(control: Control): void {
  95. this.removeControl(control);
  96. for (var index = 0; index < this._children.length; index++) {
  97. if (this._children[index].zIndex > control.zIndex) {
  98. this._children.splice(index, 0, control);
  99. return;
  100. }
  101. }
  102. this._children.push(control);
  103. control.parent = this;
  104. this._markAsDirty();
  105. }
  106. public _markMatrixAsDirty(): void {
  107. super._markMatrixAsDirty();
  108. for (var index = 0; index < this._children.length; index++) {
  109. this._children[index]._markMatrixAsDirty();
  110. }
  111. }
  112. public _markAllAsDirty(): void {
  113. super._markAllAsDirty();
  114. for (var index = 0; index < this._children.length; index++) {
  115. this._children[index]._markAllAsDirty();
  116. }
  117. }
  118. protected _localDraw(context: CanvasRenderingContext2D): void {
  119. if (this._background) {
  120. if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
  121. context.shadowColor = this.shadowColor;
  122. context.shadowBlur = this.shadowBlur;
  123. context.shadowOffsetX = this.shadowOffsetX;
  124. context.shadowOffsetY = this.shadowOffsetY;
  125. }
  126. context.fillStyle = this._background;
  127. context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
  128. if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
  129. context.shadowBlur = 0;
  130. context.shadowOffsetX = 0;
  131. context.shadowOffsetY = 0;
  132. }
  133. }
  134. }
  135. public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
  136. super._link(root, host);
  137. for (var child of this._children) {
  138. child._link(root, host);
  139. }
  140. }
  141. public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
  142. if (!this.isVisible || this.notRenderable) {
  143. return;
  144. }
  145. context.save();
  146. this._applyStates(context);
  147. if (this._processMeasures(parentMeasure, context)) {
  148. this._localDraw(context);
  149. this._clipForChildren(context);
  150. let computedWidth = -1;
  151. let computedHeight = -1;
  152. for (var child of this._children) {
  153. if (child.isVisible && !child.notRenderable) {
  154. child._tempParentMeasure.copyFrom(this._measureForChildren);
  155. child._draw(this._measureForChildren, context);
  156. if (child.onAfterDrawObservable.hasObservers()) {
  157. child.onAfterDrawObservable.notifyObservers(child);
  158. }
  159. if (this.adaptWidthToChildren && child._width.isPixel) {
  160. computedWidth = Math.max(computedWidth, child._currentMeasure.width);
  161. }
  162. if (this.adaptHeightToChildren && child._height.isPixel) {
  163. computedHeight = Math.max(computedHeight, child._currentMeasure.height);
  164. }
  165. }
  166. }
  167. if (this.adaptWidthToChildren && computedWidth >= 0) {
  168. this.width = computedWidth + "px";
  169. }
  170. if (this.adaptHeightToChildren && computedHeight >= 0) {
  171. this.height = computedHeight + "px";
  172. }
  173. }
  174. context.restore();
  175. if (this.onAfterDrawObservable.hasObservers()) {
  176. this.onAfterDrawObservable.notifyObservers(this);
  177. }
  178. }
  179. public _processPicking(x: number, y: number, type: number, pointerId:number, buttonIndex: number): boolean {
  180. if (!this.isVisible || this.notRenderable) {
  181. return false;
  182. }
  183. if (!super.contains(x, y)) {
  184. return false;
  185. }
  186. // Checking backwards to pick closest first
  187. for (var index = this._children.length - 1; index >= 0; index--) {
  188. var child = this._children[index];
  189. if (child._processPicking(x, y, type, pointerId, buttonIndex)) {
  190. return true;
  191. }
  192. }
  193. if (!this.isHitTestVisible) {
  194. return false;
  195. }
  196. return this._processObservables(type, x, y, pointerId, buttonIndex);
  197. }
  198. protected _clipForChildren(context: CanvasRenderingContext2D): void {
  199. // DO nothing
  200. }
  201. protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
  202. super._additionalProcessing(parentMeasure, context);
  203. this._measureForChildren.copyFrom(this._currentMeasure);
  204. }
  205. public dispose() {
  206. super.dispose();
  207. for (var control of this._children) {
  208. control.dispose();
  209. }
  210. }
  211. }
  212. }