Browse Source

second stage for gui

David Catuhe 8 years ago
parent
commit
8717505761

+ 17 - 6
gui/src/advancedDynamicTexture.js

@@ -19,8 +19,9 @@ var BABYLON;
                 var _this = _super.call(this, name, {}, scene, false, BABYLON.Texture.NEAREST_SAMPLINGMODE, BABYLON.Engine.TEXTUREFORMAT_RGBA) || this;
                 _this._dirty = false;
                 _this._rootContainer = new GUI.Container("root");
-                _this._resizeObserver = _this.getScene().getEngine().onResizeObservable.add(function () { return _this._markAsDirty(); });
+                _this._resizeObserver = _this.getScene().getEngine().onResizeObservable.add(function () { return _this._onResize(); });
                 _this._renderObserver = _this.getScene().onBeforeRenderObservable.add(function () { return _this._checkUpdate(); });
+                _this._onResize();
                 return _this;
             }
             Object.defineProperty(AdvancedDynamicTexture.prototype, "background", {
@@ -51,6 +52,21 @@ var BABYLON;
                 this.getScene().getEngine().onResizeObservable.remove(this._resizeObserver);
                 _super.prototype.dispose.call(this);
             };
+            AdvancedDynamicTexture.prototype._onResize = function () {
+                // Check size
+                var engine = this.getScene().getEngine();
+                var textureSize = this.getSize();
+                var renderWidth = engine.getRenderWidth();
+                var renderHeight = engine.getRenderHeight();
+                if (textureSize.width !== renderWidth || textureSize.height !== renderHeight) {
+                    this.scaleTo(renderWidth, renderHeight);
+                }
+                // Update constant pixel resources            
+                var scaleX = renderWidth / 1000.0;
+                var scaleY = renderHeight / 1000.0;
+                this._rootContainer._rescale(scaleX, scaleY);
+                this._markAsDirty();
+            };
             AdvancedDynamicTexture.prototype._markAsDirty = function () {
                 this._dirty = true;
             };
@@ -63,14 +79,9 @@ var BABYLON;
                 this.update();
             };
             AdvancedDynamicTexture.prototype._render = function () {
-                // Check size
                 var engine = this.getScene().getEngine();
-                var textureSize = this.getSize();
                 var renderWidth = engine.getRenderWidth();
                 var renderHeight = engine.getRenderHeight();
-                if (textureSize.width !== renderWidth || textureSize.height !== renderHeight) {
-                    this.scaleTo(renderWidth, renderHeight);
-                }
                 // Clear
                 var context = this.getContext();
                 if (this._background) {

+ 23 - 7
gui/src/advancedDynamicTexture.ts

@@ -24,8 +24,10 @@ module BABYLON.GUI {
         constructor(name: string, scene: Scene) {
             super(name, {}, scene, false, Texture.NEAREST_SAMPLINGMODE, Engine.TEXTUREFORMAT_RGBA);
 
-            this._resizeObserver = this.getScene().getEngine().onResizeObservable.add(() => this._markAsDirty());
+            this._resizeObserver = this.getScene().getEngine().onResizeObservable.add(() => this._onResize());
             this._renderObserver = this.getScene().onBeforeRenderObservable.add(() => this._checkUpdate());
+
+            this._onResize();
         }
 
         public addControl(control: Control): AdvancedDynamicTexture {
@@ -47,6 +49,26 @@ module BABYLON.GUI {
             super.dispose();
         }
 
+        private _onResize(): void {
+            // Check size
+            var engine = this.getScene().getEngine();
+            var textureSize = this.getSize();
+            var renderWidth = engine.getRenderWidth();
+            var renderHeight = engine.getRenderHeight();
+
+            if (textureSize.width !== renderWidth || textureSize.height !== renderHeight) {
+                this.scaleTo(renderWidth, renderHeight);
+            }
+
+            // Update constant pixel resources            
+            var scaleX = renderWidth / 1000.0;
+            var scaleY = renderHeight / 1000.0;
+
+            this._rootContainer._rescale(scaleX, scaleY);
+
+            this._markAsDirty();
+        }
+
         public _markAsDirty() {
             this._dirty = true;
         }
@@ -62,16 +84,10 @@ module BABYLON.GUI {
         }
 
         private _render(): void {
-            // Check size
             var engine = this.getScene().getEngine();
-            var textureSize = this.getSize();
             var renderWidth = engine.getRenderWidth();
             var renderHeight = engine.getRenderHeight();
 
-            if (textureSize.width !== renderWidth || textureSize.height !== renderHeight) {
-                this.scaleTo(renderWidth, renderHeight);
-            }
-
             // Clear
             var context = this.getContext();
             if (this._background) {

+ 8 - 6
gui/src/controls/container.js

@@ -53,18 +53,20 @@ var BABYLON;
             Container.prototype._draw = function (parentMeasure, context) {
                 this._currentMeasure = parentMeasure.copy();
                 context.save();
-                if (this.font) {
-                    context.font = this.font;
-                }
-                if (this.color) {
-                    context.fillStyle = this.color;
-                }
+                this.applyStates(context);
                 for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
                     var child = _a[_i];
                     child._draw(this._currentMeasure, context);
                 }
                 context.restore();
             };
+            Container.prototype._rescale = function (scaleX, scaleY) {
+                _super.prototype._rescale.call(this, scaleX, scaleY);
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._rescale(scaleX, scaleY);
+                }
+            };
             return Container;
         }(GUI.Control));
         GUI.Container = Container;

+ 9 - 7
gui/src/controls/container.ts

@@ -53,18 +53,20 @@ module BABYLON.GUI {
 
             context.save();
             
-            if (this.font) {
-                context.font = this.font;
-            }
-
-            if (this.color) {
-                context.fillStyle = this.color;
-            }
+            this.applyStates(context);
 
             for (var child of this._children) {
                 child._draw(this._currentMeasure, context);
             }
             context.restore();
         }
+
+        public _rescale(scaleX: number, scaleY: number) {
+            super._rescale(scaleX, scaleY);
+
+            for (var child of this._children) {
+                child._rescale(scaleX, scaleY);
+            }
+        }
     }    
 }

+ 7 - 6
gui/src/controls/contentControl.js

@@ -41,18 +41,19 @@ var BABYLON;
             ContentControl.prototype._draw = function (parentMeasure, context) {
                 this._currentMeasure = parentMeasure.copy();
                 context.save();
-                if (this.font) {
-                    context.font = this.font;
-                }
-                if (this.color) {
-                    context.fillStyle = this.color;
-                }
+                this.applyStates(context);
                 this._localDraw(context);
                 if (this._child) {
                     this._child._draw(this._currentMeasure, context);
                 }
                 context.restore();
             };
+            ContentControl.prototype._rescale = function (scaleX, scaleY) {
+                _super.prototype._rescale.call(this, scaleX, scaleY);
+                if (this._child) {
+                    this._child._rescale(scaleX, scaleY);
+                }
+            };
             return ContentControl;
         }(GUI.Control));
         GUI.ContentControl = ContentControl;

+ 9 - 7
gui/src/controls/contentControl.ts

@@ -32,13 +32,7 @@ module BABYLON.GUI {
 
             context.save();
             
-            if (this.font) {
-                context.font = this.font;
-            }
-
-            if (this.color) {
-                context.fillStyle = this.color;
-            }
+            this.applyStates(context);
 
             this._localDraw(context);
 
@@ -47,5 +41,13 @@ module BABYLON.GUI {
             }
             context.restore();
         }
+
+        public _rescale(scaleX: number, scaleY: number) {
+            super._rescale(scaleX, scaleY);
+
+            if (this._child) {
+                this._child._rescale(scaleX, scaleY);
+            }
+        }
     }    
 }

+ 49 - 9
gui/src/controls/control.js

@@ -7,8 +7,10 @@ var BABYLON;
             function Control(name) {
                 this.name = name;
                 this._zIndex = 0;
+                this._fontSize = 18;
                 this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
                 this._verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
+                this.fontFamily = "Arial";
             }
             Object.defineProperty(Control.prototype, "horizontalAlignment", {
                 get: function () {
@@ -38,17 +40,30 @@ var BABYLON;
                 enumerable: true,
                 configurable: true
             });
-            Object.defineProperty(Control.prototype, "font", {
+            Object.defineProperty(Control.prototype, "fontFamily", {
                 get: function () {
-                    return this._font;
+                    return this._fontFamily;
                 },
                 set: function (value) {
-                    if (this._font === value) {
+                    if (this._fontFamily === value) {
                         return;
                     }
-                    this._font = value;
-                    this._fontHeight = Control._GetFontHeight(this._font);
-                    this._markAsDirty();
+                    this._fontFamily = value;
+                    this._prepareFont();
+                },
+                enumerable: true,
+                configurable: true
+            });
+            Object.defineProperty(Control.prototype, "fontSize", {
+                get: function () {
+                    return this._fontSize;
+                },
+                set: function (value) {
+                    if (this._fontSize === value) {
+                        return;
+                    }
+                    this._fontSize = value;
+                    this._prepareFont();
                 },
                 enumerable: true,
                 configurable: true
@@ -90,10 +105,31 @@ var BABYLON;
             Control.prototype._setRoot = function (root) {
                 this._root = root;
             };
+            Control.prototype.applyStates = function (context) {
+                if (this._font) {
+                    context.font = this._font;
+                }
+                if (this._color) {
+                    context.fillStyle = this._color;
+                }
+            };
             Control.prototype._draw = function (parentMeasure, context) {
                 this._currentMeasure = parentMeasure.copy();
                 // Do nothing
             };
+            Control.prototype._rescale = function (scaleX, scaleY) {
+                this._scaleX = scaleX;
+                this._scaleY = scaleY;
+                this._prepareFont();
+            };
+            Control.prototype._prepareFont = function () {
+                if (!this._fontFamily) {
+                    return;
+                }
+                this._font = (this._fontSize * this._scaleX) + "px " + this._fontFamily;
+                this._fontOffset = Control._GetFontOffset(this._font);
+                this._markAsDirty();
+            };
             Object.defineProperty(Control, "HORIZONTAL_ALIGNMENT_LEFT", {
                 get: function () {
                     return Control._HORIZONTAL_ALIGNMENT_LEFT;
@@ -136,7 +172,7 @@ var BABYLON;
                 enumerable: true,
                 configurable: true
             });
-            Control._GetFontHeight = function (font) {
+            Control._GetFontOffset = function (font) {
                 if (Control._FontHeightSizes[font]) {
                     return Control._FontHeightSizes[font];
                 }
@@ -152,15 +188,19 @@ var BABYLON;
                 div.appendChild(text);
                 div.appendChild(block);
                 document.body.appendChild(div);
+                var fontAscent = 0;
                 var fontHeight = 0;
                 try {
                     fontHeight = block.getBoundingClientRect().top - text.getBoundingClientRect().top;
+                    block.style.verticalAlign = "baseline";
+                    fontAscent = block.getBoundingClientRect().top - text.getBoundingClientRect().top;
                 }
                 finally {
                     div.remove();
                 }
-                Control._FontHeightSizes[font] = fontHeight;
-                return fontHeight;
+                var result = { ascent: fontAscent, height: fontHeight, descent: fontHeight - fontAscent };
+                Control._FontHeightSizes[font] = result;
+                return result;
             };
             ;
             return Control;

+ 58 - 12
gui/src/controls/control.ts

@@ -5,9 +5,13 @@ module BABYLON.GUI {
         private _zIndex = 0;
         public _root: Container;
         public _currentMeasure: Measure;
+        private _scaleX: number;
+        private _scaleY: number;
+        private _fontFamily: string;
+        private _fontSize = 18;
         private _font: string;
         private _lastMeasuredFont: string;
-        protected _fontHeight: number;
+        protected _fontOffset: {ascent: number, height: number, descent: number};
         private _color: string;
         private _horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
         private _verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
@@ -38,18 +42,30 @@ module BABYLON.GUI {
             this._markAsDirty();
         } 
 
-        public get font(): string {
-            return this._font;
+        public get fontFamily(): string {
+            return this._fontFamily;
         }
 
-        public set font(value: string) {
-            if (this._font === value) {
+        public set fontFamily(value: string) {
+            if (this._fontFamily === value) {
                 return;
             }
 
-            this._font = value;
-            this._fontHeight = Control._GetFontHeight(this._font);
-            this._markAsDirty();
+            this._fontFamily = value;
+            this._prepareFont();
+        }
+
+        public get fontSize(): number {
+            return this._fontSize;
+        }
+
+        public set fontSize(value: number) {
+            if (this._fontSize === value) {
+                return;
+            }
+
+            this._fontSize = value;
+            this._prepareFont();
         }
 
         public get color(): string {
@@ -79,6 +95,7 @@ module BABYLON.GUI {
         }
 
         constructor(public name: string) {
+            this.fontFamily = "Arial";
         }
 
         protected _markAsDirty(): void {
@@ -92,11 +109,37 @@ module BABYLON.GUI {
             this._root = root;
         }
 
+        protected applyStates(context: CanvasRenderingContext2D): void {
+            if (this._font) {
+                context.font = this._font;
+            }
+
+            if (this._color) {
+                context.fillStyle = this._color;
+            }
+        }
+
         public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             this._currentMeasure = parentMeasure.copy();
             // Do nothing
         }
 
+        public _rescale(scaleX: number, scaleY: number) {
+            this._scaleX = scaleX;
+            this._scaleY = scaleY;
+
+            this._prepareFont();
+        }
+
+        private _prepareFont() {
+            if (!this._fontFamily) {
+                return;
+            }
+            this._font = (this._fontSize * this._scaleX) + "px " + this._fontFamily;
+            this._fontOffset = Control._GetFontOffset(this._font);
+            this._markAsDirty();
+        }
+
         // Statics
         private static _HORIZONTAL_ALIGNMENT_LEFT = 0;
         private static _HORIZONTAL_ALIGNMENT_RIGHT = 1;
@@ -131,7 +174,7 @@ module BABYLON.GUI {
 
         private static _FontHeightSizes = {};
 
-        public static _GetFontHeight(font: string): number {
+        public static _GetFontOffset(font: string): {ascent: number, height: number, descent: number} {
 
             if (Control._FontHeightSizes[font]) {
                 return Control._FontHeightSizes[font];
@@ -153,16 +196,19 @@ module BABYLON.GUI {
 
             document.body.appendChild(div);
 
+            var fontAscent = 0;
             var fontHeight = 0;
             try {
                 fontHeight = block.getBoundingClientRect().top - text.getBoundingClientRect().top;
+                block.style.verticalAlign = "baseline";
+                fontAscent = block.getBoundingClientRect().top - text.getBoundingClientRect().top;
             } finally {
                 div.remove();
             }
+            var result = { ascent: fontAscent, height: fontHeight, descent: fontHeight - fontAscent };
+            Control._FontHeightSizes[font] = result;
 
-            Control._FontHeightSizes[font] = fontHeight;
-
-            return fontHeight;
+            return result;
         };
     }    
 }

+ 6 - 11
gui/src/controls/textBlock.js

@@ -37,12 +37,7 @@ var BABYLON;
             });
             TextBlock.prototype._draw = function (parentMeasure, context) {
                 context.save();
-                if (this.font) {
-                    context.font = this.font;
-                }
-                if (this.color) {
-                    context.fillStyle = this.color;
-                }
+                this.applyStates(context);
                 this._prepare(parentMeasure, context);
                 context.fillText(this.text, this._currentMeasure.left, this._currentMeasure.top);
                 context.restore();
@@ -64,18 +59,18 @@ var BABYLON;
                         x = (width - textSize.width) / 2;
                         break;
                 }
-                if (!this._fontHeight) {
-                    this._fontHeight = GUI.Control._GetFontHeight(context.font);
+                if (!this._fontOffset) {
+                    this._fontOffset = GUI.Control._GetFontOffset(context.font);
                 }
                 switch (this.verticalAlignment) {
                     case GUI.Control.VERTICAL_ALIGNMENT_TOP:
-                        y = this._fontHeight;
+                        y = this._fontOffset.ascent;
                         break;
                     case GUI.Control.VERTICAL_ALIGNMENT_BOTTOM:
-                        y = height;
+                        y = height - this._fontOffset.descent;
                         break;
                     case GUI.Control.VERTICAL_ALIGNMENT_CENTER:
-                        y = (height / 2) + this._fontHeight;
+                        y = (height / 2) + (this._fontOffset.ascent - this._fontOffset.height / 2);
                         break;
                 }
                 this._currentMeasure = new GUI.Measure(parentMeasure.left + x, parentMeasure.top + y, width, height);

+ 7 - 12
gui/src/controls/textBlock.ts

@@ -24,13 +24,8 @@ module BABYLON.GUI {
 
         public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
             context.save();
-            if (this.font) {
-                context.font = this.font;
-            }
-
-            if (this.color) {
-                context.fillStyle = this.color;
-            }
+            
+            this.applyStates(context);
 
             this._prepare(parentMeasure, context)
 
@@ -59,19 +54,19 @@ module BABYLON.GUI {
                     break;
             }
 
-            if (!this._fontHeight) {
-                this._fontHeight = Control._GetFontHeight(context.font);
+            if (!this._fontOffset) {
+                this._fontOffset = Control._GetFontOffset(context.font);
             }
 
             switch (this.verticalAlignment) {
                 case Control.VERTICAL_ALIGNMENT_TOP:
-                    y = this._fontHeight;
+                    y = this._fontOffset.ascent;
                     break;
                 case Control.VERTICAL_ALIGNMENT_BOTTOM:
-                    y = height;
+                    y = height - this._fontOffset.descent;
                     break;
                 case Control.VERTICAL_ALIGNMENT_CENTER:
-                    y = (height /2) + this._fontHeight;
+                    y = (height /2) + (this._fontOffset.ascent - this._fontOffset.height / 2);
                     break;
             }