Browse Source

Merge pull request #1878 from nockawa/PosImprovments

Canvas2D: **breaking change** on Positioning Engine
Loïc Baumann 8 years ago
parent
commit
08ce2dc8da

+ 153 - 58
canvas2D/src/Engine/babylon.prim2dBase.ts

@@ -1178,7 +1178,7 @@
                         } else {
                         } else {
                             dstArea.width = (sourceArea.width * isx) - (dstOffset.x + rightPixels) * isx;
                             dstArea.width = (sourceArea.width * isx) - (dstOffset.x + rightPixels) * isx;
                         }
                         }
-                        
+
                         dstOffset.z = this.rightPixels;
                         dstOffset.z = this.rightPixels;
                         break;
                         break;
                     }
                     }
@@ -1208,7 +1208,7 @@
                         break;
                         break;
                     }
                     }
                 }
                 }
-                
+
             }
             }
 
 
             if (computeAxis & PrimitiveThickness.ComputeV) {
             if (computeAxis & PrimitiveThickness.ComputeV) {
@@ -1308,7 +1308,7 @@
 
 
                         break;
                         break;
                     }
                     }
-                }                
+                }
             }
             }
         }
         }
 
 
@@ -1466,7 +1466,7 @@
             dontInheritParentScale  ?: boolean,
             dontInheritParentScale  ?: boolean,
             alignToPixel            ?: boolean,
             alignToPixel            ?: boolean,
             opacity                 ?: number,
             opacity                 ?: number,
-            zOrder                  ?: number, 
+            zOrder                  ?: number,
             origin                  ?: Vector2,
             origin                  ?: Vector2,
             layoutEngine            ?: LayoutEngineBase | string,
             layoutEngine            ?: LayoutEngineBase | string,
             isVisible               ?: boolean,
             isVisible               ?: boolean,
@@ -1757,7 +1757,7 @@
         /**
         /**
          * Return the ObservableStringDictionary containing all the primitives intersecting with this one.
          * Return the ObservableStringDictionary containing all the primitives intersecting with this one.
          * The key is the primitive uid, the value is the ActorInfo object
          * The key is the primitive uid, the value is the ActorInfo object
-         * @returns {} 
+         * @returns {}
          */
          */
         public get intersectWith(): ObservableStringDictionary<ActorInfoBase> {
         public get intersectWith(): ObservableStringDictionary<ActorInfoBase> {
             if (!this._actorInfo) {
             if (!this._actorInfo) {
@@ -1994,6 +1994,9 @@
             return this.actualPosition.x;
             return this.actualPosition.x;
         }
         }
 
 
+        /**
+         * DO NOT INVOKE for internal purpose only
+         */
         public set actualX(val: number) {
         public set actualX(val: number) {
             this._actualPosition.x = val;
             this._actualPosition.x = val;
             this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, this._actualPosition);
             this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, this._actualPosition);
@@ -2007,6 +2010,9 @@
             return this.actualPosition.y;
             return this.actualPosition.y;
         }
         }
 
 
+        /**
+        * DO NOT INVOKE for internal purpose only
+        */
         public set actualY(val: number) {
         public set actualY(val: number) {
             this._actualPosition.y = val;
             this._actualPosition.y = val;
             this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, this._actualPosition);
             this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, this._actualPosition);
@@ -2027,20 +2033,44 @@
         }
         }
 
 
         public set position(value: Vector2) {
         public set position(value: Vector2) {
-            if (!this._checkPositionChange()) {
+            //if (!this._checkPositionChange()) {
+            //    return;
+            //}
+            if (this._checkUseMargin()) {
+                switch (this._marginAlignment.horizontal) {
+                    case PrimitiveAlignment.AlignLeft:
+                    case PrimitiveAlignment.AlignStretch:
+                    case PrimitiveAlignment.AlignCenter:
+                        this.margin.leftPixels = value.x;
+                        break;
+                    case PrimitiveAlignment.AlignRight:
+                        this.margin.rightPixels = value.x;
+                        break;
+                    }
+                switch (this._marginAlignment.vertical) {
+                    case PrimitiveAlignment.AlignBottom:
+                    case PrimitiveAlignment.AlignStretch:
+                    case PrimitiveAlignment.AlignCenter:
+                        this.margin.bottomPixels = value.y;
+                        break;
+                    case PrimitiveAlignment.AlignTop:
+                        this.margin.topPixels = value.y;
+                        break;
+                }
                 return;
                 return;
-            }
-            if (!value) {
-                this._position = null;
             } else {
             } else {
-                if (!this._position) {
-                    this._position = value.clone();
+                if (!value) {
+                    this._position = null;
                 } else {
                 } else {
-                    this._position.copyFrom(value);
+                    if (!this._position) {
+                        this._position = value.clone();
+                    } else {
+                        this._position.copyFrom(value);
+                    }
                 }
                 }
+                this._actualPosition = null;
+                this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, value);
             }
             }
-            this._actualPosition = null;
-            this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, value);
         }
         }
 
 
         /**
         /**
@@ -2056,24 +2086,38 @@
         }
         }
 
 
         public set x(value: number) {
         public set x(value: number) {
-            if (!this._checkPositionChange()) {
-                return;
-            }
+            //if (!this._checkPositionChange()) {
+            //    return;
+            //}
             if (value == null) {
             if (value == null) {
                 throw new Error(`Can't set a null x in primitive ${this.id}, only the position can be turned to null`);
                 throw new Error(`Can't set a null x in primitive ${this.id}, only the position can be turned to null`);
             }
             }
-            if (!this._position) {
-                this._position = Vector2.Zero();
-            }
-
-            if (this._position.x === value) {
+            if (this._checkUseMargin()) {
+                switch (this._marginAlignment.horizontal) {
+                    case PrimitiveAlignment.AlignLeft:
+                    case PrimitiveAlignment.AlignStretch:
+                    case PrimitiveAlignment.AlignCenter:
+                        this.margin.leftPixels = value;
+                        break;
+                    case PrimitiveAlignment.AlignRight:
+                        this.margin.rightPixels = value;
+                        break;
+                    }
                 return;
                 return;
-            }
+            } else {
+                if (!this._position) {
+                    this._position = Vector2.Zero();
+                }
+
+                if (this._position.x === value) {
+                    return;
+                }
 
 
-            this._position.x = value;
-            this._actualPosition = null;
-            this._triggerPropertyChanged(Prim2DBase.positionProperty, value);
-            this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, value);
+                this._position.x = value;
+                this._actualPosition = null;
+                this._triggerPropertyChanged(Prim2DBase.positionProperty, value);
+                this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, value);
+            }
         }
         }
 
 
         /**
         /**
@@ -2089,24 +2133,38 @@
         }
         }
 
 
         public set y(value: number) {
         public set y(value: number) {
-            if (!this._checkPositionChange()) {
-                return;
-            }
+            //if (!this._checkPositionChange()) {
+            //    return;
+            //}
             if (value == null) {
             if (value == null) {
                 throw new Error(`Can't set a null y in primitive ${this.id}, only the position can be turned to null`);
                 throw new Error(`Can't set a null y in primitive ${this.id}, only the position can be turned to null`);
             }
             }
-            if (!this._position) {
-                this._position = Vector2.Zero();
-            }
-
-            if (this._position.y === value) {
+            if (this._checkUseMargin()) {
+                switch (this._marginAlignment.vertical) {
+                    case PrimitiveAlignment.AlignBottom:
+                    case PrimitiveAlignment.AlignStretch:
+                    case PrimitiveAlignment.AlignCenter:
+                        this.margin.bottomPixels = value;
+                        break;
+                    case PrimitiveAlignment.AlignTop:
+                        this.margin.topPixels = value;
+                        break;
+                }
                 return;
                 return;
-            }
+            } else {
+                if (!this._position) {
+                    this._position = Vector2.Zero();
+                }
+
+                if (this._position.y === value) {
+                    return;
+                }
 
 
-            this._position.y = value;
-            this._actualPosition = null;
-            this._triggerPropertyChanged(Prim2DBase.positionProperty, value);
-            this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, value);
+                this._position.y = value;
+                this._actualPosition = null;
+                this._triggerPropertyChanged(Prim2DBase.positionProperty, value);
+                this._triggerPropertyChanged(Prim2DBase.actualPositionProperty, value);
+            }
         }
         }
 
 
         private static boundinbBoxReentrency: number = -1;
         private static boundinbBoxReentrency: number = -1;
@@ -2153,7 +2211,7 @@
 
 
                 return this._internalSize || Prim2DBase._nullSize;
                 return this._internalSize || Prim2DBase._nullSize;
             } else {
             } else {
-                C2DLogging.setPostMessage(() => "user set size");                
+                C2DLogging.setPostMessage(() => "user set size");
             }
             }
             return this._size || Prim2DBase._nullSize;
             return this._size || Prim2DBase._nullSize;
         }
         }
@@ -2484,6 +2542,16 @@
         }
         }
 
 
         /**
         /**
+         * Set the margin from a string value
+         * @param value is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
+         * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
+         */
+        public setMargin(value: string) {
+            this.margin.fromString(value);
+            this._updatePositioningState();
+        }
+
+        /**
          * Check for both margin and marginAlignment, return true if at least one of them is specified with a non default value
          * Check for both margin and marginAlignment, return true if at least one of them is specified with a non default value
          */
          */
         public get _hasMargin(): boolean {
         public get _hasMargin(): boolean {
@@ -2517,6 +2585,15 @@
             this._updatePositioningState();
             this._updatePositioningState();
         }
         }
 
 
+        /**
+         * Set the padding from a string value
+         * @param value is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
+         * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.         */
+        public setPadding(value: string) {
+            this.padding.fromString(value);
+            this._updatePositioningState();
+        }
+
         private get _hasPadding(): boolean {
         private get _hasPadding(): boolean {
             return this._padding !== null && !this._padding.isDefault;
             return this._padding !== null && !this._padding.isDefault;
         }
         }
@@ -2543,6 +2620,15 @@
         }
         }
 
 
         /**
         /**
+         * Set the margin's horizontal and or vertical alignments from a string value.
+         * @param value can be: [<h:|horizontal:><left|right|center|stretch>], [<v:|vertical:><top|bottom|center|stretch>]
+         */
+        public setMarginalignment(value: string) {
+            this.marginAlignment.fromString(value);
+            this._updatePositioningState();
+        }
+
+        /**
          * Check if there a marginAlignment specified (non null and not default)
          * Check if there a marginAlignment specified (non null and not default)
          */
          */
         public get _hasMarginAlignment(): boolean {
         public get _hasMarginAlignment(): boolean {
@@ -2910,7 +2996,7 @@
 
 
                 this._clearFlags(SmartPropertyPrim.flagBoundingInfoDirty);
                 this._clearFlags(SmartPropertyPrim.flagBoundingInfoDirty);
             } else {
             } else {
-                C2DLogging.setPostMessage(() => "cache hit");                
+                C2DLogging.setPostMessage(() => "cache hit");
             }
             }
             return this._boundingInfo;
             return this._boundingInfo;
         }
         }
@@ -2950,7 +3036,7 @@
 
 
                 this._clearFlags(SmartPropertyPrim.flagLayoutBoundingInfoDirty);
                 this._clearFlags(SmartPropertyPrim.flagLayoutBoundingInfoDirty);
             } else {
             } else {
-                C2DLogging.setPostMessage(() => "cache hit");                
+                C2DLogging.setPostMessage(() => "cache hit");
             }
             }
             return usePositioning ? this._layoutBoundingInfo : this.boundingInfo;
             return usePositioning ? this._layoutBoundingInfo : this.boundingInfo;
         }
         }
@@ -3128,7 +3214,7 @@
             prims[3][0].levelVisible = true;
             prims[3][0].levelVisible = true;
 
 
             // Current offset
             // Current offset
-            let curOffset = Vector2.Zero(); 
+            let curOffset = Vector2.Zero();
 
 
             // Store the area info of the layout area
             // Store the area info of the layout area
             let curAreaIndex = 0;
             let curAreaIndex = 0;
@@ -3353,7 +3439,7 @@
                     return ownerGroup.intersect(intersectInfo);
                     return ownerGroup.intersect(intersectInfo);
                 } finally  {
                 } finally  {
                     Prim2DBase._bypassGroup2DExclusion = false;
                     Prim2DBase._bypassGroup2DExclusion = false;
-                } 
+                }
             }
             }
 
 
             // If we're testing a cachedGroup, we must reject pointer outside its levelBoundingInfo because children primitives could be partially clipped outside so we must not accept them as intersected when it's the case (because they're not visually visible).
             // If we're testing a cachedGroup, we must reject pointer outside its levelBoundingInfo because children primitives could be partially clipped outside so we must not accept them as intersected when it's the case (because they're not visually visible).
@@ -3667,18 +3753,27 @@
 
 
         }
         }
 
 
-        private _checkPositionChange(): boolean {
-            if (this.parent && this.parent.layoutEngine.isChildPositionAllowed === false) {
-                console.log(`Can't manually set the position of ${this.id}, the Layout Engine of its parent doesn't allow it`);
+        //private _checkPositionChange(): boolean {
+        //    if (this.parent && this.parent.layoutEngine.isChildPositionAllowed === false) {
+        //        console.log(`Can't manually set the position of ${this.id}, the Layout Engine of its parent doesn't allow it`);
+        //        return false;
+        //    }
+        //    if (this._isFlagSet(SmartPropertyPrim.flagUsePositioning)) {
+        //        if (<any>this instanceof Group2D && (<Group2D><any>this).trackedNode == null) {
+        //            console.log(`You can't set the position/x/y of ${this.id} properties while positioning engine is used (margin, margin alignment and/or padding are set`);
+        //            return false;
+        //        }
+        //    }
+        //    return true;
+        //}
+
+        private _checkUseMargin(): boolean {
+            // Special cae: tracked node
+            if (<any>this instanceof Group2D && (<Group2D><any>this).trackedNode != null) {
                 return false;
                 return false;
             }
             }
-            if (this._isFlagSet(SmartPropertyPrim.flagUsePositioning)) {
-                if (<any>this instanceof Group2D && (<Group2D><any>this).trackedNode == null) {
-                    console.log(`You can't set the position/x/y of ${this.id} properties while positioning engine is used (margin, margin alignment and/or padding are set`);
-                    return false;
-                }
-            }
-            return true;
+
+            return this._isFlagSet(SmartPropertyPrim.flagUsePositioning);
         }
         }
 
 
         @logMethod("", true)
         @logMethod("", true)
@@ -3799,7 +3894,7 @@
             this._updateCachesProcessStep = ownerProcessStep;
             this._updateCachesProcessStep = ownerProcessStep;
 
 
             this.owner.addUpdateCachedStateCounter(1);
             this.owner.addUpdateCachedStateCounter(1);
-            
+
             // Check if the parent is synced
             // Check if the parent is synced
             if (this._parent && ((this._parent._globalTransformProcessStep !== this.owner._globalTransformProcessStep) || this._parent._areSomeFlagsSet(SmartPropertyPrim.flagLayoutDirty | SmartPropertyPrim.flagPositioningDirty | SmartPropertyPrim.flagZOrderDirty))) {
             if (this._parent && ((this._parent._globalTransformProcessStep !== this.owner._globalTransformProcessStep) || this._parent._areSomeFlagsSet(SmartPropertyPrim.flagLayoutDirty | SmartPropertyPrim.flagPositioningDirty | SmartPropertyPrim.flagZOrderDirty))) {
                 this._parent.updateCachedStates(false);
                 this._parent.updateCachedStates(false);
@@ -4197,7 +4292,7 @@
         }
         }
 
 
         protected onSetOwner() {
         protected onSetOwner() {
-            
+
         }
         }
 
 
         private static _zOrderChangedNotifList = new Array<Prim2DBase>();
         private static _zOrderChangedNotifList = new Array<Prim2DBase>();
@@ -4454,7 +4549,7 @@
         // If a child prim has an older _parentTransformStep it means the child's transform should be updated
         // If a child prim has an older _parentTransformStep it means the child's transform should be updated
         protected _globalTransformStep: number;
         protected _globalTransformStep: number;
 
 
-        // Stores the previous 
+        // Stores the previous
         protected _globalTransformProcessStep: number;
         protected _globalTransformProcessStep: number;
         protected _prepareProcessStep: number;
         protected _prepareProcessStep: number;
         protected _updateCachesProcessStep: number;
         protected _updateCachesProcessStep: number;

+ 23 - 1
dist/preview release/canvas2D/babylon.canvas2d.d.ts

@@ -2191,10 +2191,16 @@ declare module BABYLON {
         /**
         /**
          * Shortcut to actualPosition.x
          * Shortcut to actualPosition.x
          */
          */
+        /**
+         * DO NOT INVOKE for internal purpose only
+         */
         actualX: number;
         actualX: number;
         /**
         /**
          * Shortcut to actualPosition.y
          * Shortcut to actualPosition.y
          */
          */
+        /**
+        * DO NOT INVOKE for internal purpose only
+        */
         actualY: number;
         actualY: number;
         /**
         /**
          * Position of the primitive, relative to its parent.
          * Position of the primitive, relative to its parent.
@@ -2254,13 +2260,29 @@ declare module BABYLON {
         readonly isManualZOrder: boolean;
         readonly isManualZOrder: boolean;
         margin: PrimitiveThickness;
         margin: PrimitiveThickness;
         /**
         /**
+         * Set the margin from a string value
+         * @param value is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
+         * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
+         */
+        setMargin(value: string): void;
+        /**
          * Check for both margin and marginAlignment, return true if at least one of them is specified with a non default value
          * Check for both margin and marginAlignment, return true if at least one of them is specified with a non default value
          */
          */
         readonly _hasMargin: boolean;
         readonly _hasMargin: boolean;
         padding: PrimitiveThickness;
         padding: PrimitiveThickness;
+        /**
+         * Set the padding from a string value
+         * @param value is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
+         * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.         */
+        setPadding(value: string): void;
         private readonly _hasPadding;
         private readonly _hasPadding;
         marginAlignment: PrimitiveAlignment;
         marginAlignment: PrimitiveAlignment;
         /**
         /**
+         * Set the margin's horizontal and or vertical alignments from a string value.
+         * @param value can be: [<h:|horizontal:><left|right|center|stretch>], [<v:|vertical:><top|bottom|center|stretch>]
+         */
+        setMarginalignment(value: string): void;
+        /**
          * Check if there a marginAlignment specified (non null and not default)
          * Check if there a marginAlignment specified (non null and not default)
          */
          */
         readonly _hasMarginAlignment: boolean;
         readonly _hasMarginAlignment: boolean;
@@ -2465,7 +2487,7 @@ declare module BABYLON {
         protected updateCachedStatesOf(list: Prim2DBase[], recurse: boolean): void;
         protected updateCachedStatesOf(list: Prim2DBase[], recurse: boolean): void;
         private _parentLayoutDirty();
         private _parentLayoutDirty();
         protected _setLayoutDirty(): void;
         protected _setLayoutDirty(): void;
-        private _checkPositionChange();
+        private _checkUseMargin();
         protected _positioningDirty(): void;
         protected _positioningDirty(): void;
         protected _spreadActualOpacityChanged(): void;
         protected _spreadActualOpacityChanged(): void;
         private _changeLayoutEngine(engine);
         private _changeLayoutEngine(engine);

+ 134 - 41
dist/preview release/canvas2D/babylon.canvas2d.js

@@ -7376,6 +7376,9 @@ var BABYLON;
             get: function () {
             get: function () {
                 return this.actualPosition.x;
                 return this.actualPosition.x;
             },
             },
+            /**
+             * DO NOT INVOKE for internal purpose only
+             */
             set: function (val) {
             set: function (val) {
                 this._actualPosition.x = val;
                 this._actualPosition.x = val;
                 this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, this._actualPosition);
                 this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, this._actualPosition);
@@ -7390,6 +7393,9 @@ var BABYLON;
             get: function () {
             get: function () {
                 return this.actualPosition.y;
                 return this.actualPosition.y;
             },
             },
+            /**
+            * DO NOT INVOKE for internal purpose only
+            */
             set: function (val) {
             set: function (val) {
                 this._actualPosition.y = val;
                 this._actualPosition.y = val;
                 this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, this._actualPosition);
                 this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, this._actualPosition);
@@ -7411,22 +7417,47 @@ var BABYLON;
                 return this._position;
                 return this._position;
             },
             },
             set: function (value) {
             set: function (value) {
-                if (!this._checkPositionChange()) {
+                //if (!this._checkPositionChange()) {
+                //    return;
+                //}
+                if (this._checkUseMargin()) {
+                    switch (this._marginAlignment.horizontal) {
+                        case PrimitiveAlignment.AlignLeft:
+                        case PrimitiveAlignment.AlignStretch:
+                        case PrimitiveAlignment.AlignCenter:
+                            this.margin.leftPixels = value.x;
+                            break;
+                        case PrimitiveAlignment.AlignRight:
+                            this.margin.rightPixels = value.x;
+                            break;
+                    }
+                    switch (this._marginAlignment.vertical) {
+                        case PrimitiveAlignment.AlignBottom:
+                        case PrimitiveAlignment.AlignStretch:
+                        case PrimitiveAlignment.AlignCenter:
+                            this.margin.bottomPixels = value.y;
+                            break;
+                        case PrimitiveAlignment.AlignTop:
+                            this.margin.topPixels = value.y;
+                            break;
+                    }
                     return;
                     return;
                 }
                 }
-                if (!value) {
-                    this._position = null;
-                }
                 else {
                 else {
-                    if (!this._position) {
-                        this._position = value.clone();
+                    if (!value) {
+                        this._position = null;
                     }
                     }
                     else {
                     else {
-                        this._position.copyFrom(value);
+                        if (!this._position) {
+                            this._position = value.clone();
+                        }
+                        else {
+                            this._position.copyFrom(value);
+                        }
                     }
                     }
+                    this._actualPosition = null;
+                    this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
                 }
                 }
-                this._actualPosition = null;
-                this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -7443,22 +7474,37 @@ var BABYLON;
                 return this._position.x;
                 return this._position.x;
             },
             },
             set: function (value) {
             set: function (value) {
-                if (!this._checkPositionChange()) {
-                    return;
-                }
+                //if (!this._checkPositionChange()) {
+                //    return;
+                //}
                 if (value == null) {
                 if (value == null) {
                     throw new Error("Can't set a null x in primitive " + this.id + ", only the position can be turned to null");
                     throw new Error("Can't set a null x in primitive " + this.id + ", only the position can be turned to null");
                 }
                 }
-                if (!this._position) {
-                    this._position = BABYLON.Vector2.Zero();
-                }
-                if (this._position.x === value) {
+                if (this._checkUseMargin()) {
+                    switch (this._marginAlignment.horizontal) {
+                        case PrimitiveAlignment.AlignLeft:
+                        case PrimitiveAlignment.AlignStretch:
+                        case PrimitiveAlignment.AlignCenter:
+                            this.margin.leftPixels = value;
+                            break;
+                        case PrimitiveAlignment.AlignRight:
+                            this.margin.rightPixels = value;
+                            break;
+                    }
                     return;
                     return;
                 }
                 }
-                this._position.x = value;
-                this._actualPosition = null;
-                this._triggerPropertyChanged(Prim2DBase_1.positionProperty, value);
-                this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
+                else {
+                    if (!this._position) {
+                        this._position = BABYLON.Vector2.Zero();
+                    }
+                    if (this._position.x === value) {
+                        return;
+                    }
+                    this._position.x = value;
+                    this._actualPosition = null;
+                    this._triggerPropertyChanged(Prim2DBase_1.positionProperty, value);
+                    this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
+                }
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -7475,22 +7521,37 @@ var BABYLON;
                 return this._position.y;
                 return this._position.y;
             },
             },
             set: function (value) {
             set: function (value) {
-                if (!this._checkPositionChange()) {
-                    return;
-                }
+                //if (!this._checkPositionChange()) {
+                //    return;
+                //}
                 if (value == null) {
                 if (value == null) {
                     throw new Error("Can't set a null y in primitive " + this.id + ", only the position can be turned to null");
                     throw new Error("Can't set a null y in primitive " + this.id + ", only the position can be turned to null");
                 }
                 }
-                if (!this._position) {
-                    this._position = BABYLON.Vector2.Zero();
-                }
-                if (this._position.y === value) {
+                if (this._checkUseMargin()) {
+                    switch (this._marginAlignment.vertical) {
+                        case PrimitiveAlignment.AlignBottom:
+                        case PrimitiveAlignment.AlignStretch:
+                        case PrimitiveAlignment.AlignCenter:
+                            this.margin.bottomPixels = value;
+                            break;
+                        case PrimitiveAlignment.AlignTop:
+                            this.margin.topPixels = value;
+                            break;
+                    }
                     return;
                     return;
                 }
                 }
-                this._position.y = value;
-                this._actualPosition = null;
-                this._triggerPropertyChanged(Prim2DBase_1.positionProperty, value);
-                this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
+                else {
+                    if (!this._position) {
+                        this._position = BABYLON.Vector2.Zero();
+                    }
+                    if (this._position.y === value) {
+                        return;
+                    }
+                    this._position.y = value;
+                    this._actualPosition = null;
+                    this._triggerPropertyChanged(Prim2DBase_1.positionProperty, value);
+                    this._triggerPropertyChanged(Prim2DBase_1.actualPositionProperty, value);
+                }
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -7827,6 +7888,15 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        /**
+         * Set the margin from a string value
+         * @param value is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
+         * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.
+         */
+        Prim2DBase.prototype.setMargin = function (value) {
+            this.margin.fromString(value);
+            this._updatePositioningState();
+        };
         Object.defineProperty(Prim2DBase.prototype, "_hasMargin", {
         Object.defineProperty(Prim2DBase.prototype, "_hasMargin", {
             /**
             /**
              * Check for both margin and marginAlignment, return true if at least one of them is specified with a non default value
              * Check for both margin and marginAlignment, return true if at least one of them is specified with a non default value
@@ -7863,6 +7933,14 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        /**
+         * Set the padding from a string value
+         * @param value is "top: <value>, left:<value>, right:<value>, bottom:<value>" or "<value>" (same for all edges) each are optional, auto will be set if it's omitted.
+         * Values are: 'auto', 'inherit', 'XX%' for percentage, 'XXpx' or 'XX' for pixels.         */
+        Prim2DBase.prototype.setPadding = function (value) {
+            this.padding.fromString(value);
+            this._updatePositioningState();
+        };
         Object.defineProperty(Prim2DBase.prototype, "_hasPadding", {
         Object.defineProperty(Prim2DBase.prototype, "_hasPadding", {
             get: function () {
             get: function () {
                 return this._padding !== null && !this._padding.isDefault;
                 return this._padding !== null && !this._padding.isDefault;
@@ -7891,6 +7969,14 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
+        /**
+         * Set the margin's horizontal and or vertical alignments from a string value.
+         * @param value can be: [<h:|horizontal:><left|right|center|stretch>], [<v:|vertical:><top|bottom|center|stretch>]
+         */
+        Prim2DBase.prototype.setMarginalignment = function (value) {
+            this.marginAlignment.fromString(value);
+            this._updatePositioningState();
+        };
         Object.defineProperty(Prim2DBase.prototype, "_hasMarginAlignment", {
         Object.defineProperty(Prim2DBase.prototype, "_hasMarginAlignment", {
             /**
             /**
              * Check if there a marginAlignment specified (non null and not default)
              * Check if there a marginAlignment specified (non null and not default)
@@ -8960,18 +9046,25 @@ var BABYLON;
             this.onPrimBecomesDirty();
             this.onPrimBecomesDirty();
             this._setFlags(BABYLON.SmartPropertyPrim.flagLayoutDirty);
             this._setFlags(BABYLON.SmartPropertyPrim.flagLayoutDirty);
         };
         };
-        Prim2DBase.prototype._checkPositionChange = function () {
-            if (this.parent && this.parent.layoutEngine.isChildPositionAllowed === false) {
-                console.log("Can't manually set the position of " + this.id + ", the Layout Engine of its parent doesn't allow it");
+        //private _checkPositionChange(): boolean {
+        //    if (this.parent && this.parent.layoutEngine.isChildPositionAllowed === false) {
+        //        console.log(`Can't manually set the position of ${this.id}, the Layout Engine of its parent doesn't allow it`);
+        //        return false;
+        //    }
+        //    if (this._isFlagSet(SmartPropertyPrim.flagUsePositioning)) {
+        //        if (<any>this instanceof Group2D && (<Group2D><any>this).trackedNode == null) {
+        //            console.log(`You can't set the position/x/y of ${this.id} properties while positioning engine is used (margin, margin alignment and/or padding are set`);
+        //            return false;
+        //        }
+        //    }
+        //    return true;
+        //}
+        Prim2DBase.prototype._checkUseMargin = function () {
+            // Special cae: tracked node
+            if (this instanceof BABYLON.Group2D && this.trackedNode != null) {
                 return false;
                 return false;
             }
             }
-            if (this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning)) {
-                if (this instanceof BABYLON.Group2D && this.trackedNode == null) {
-                    console.log("You can't set the position/x/y of " + this.id + " properties while positioning engine is used (margin, margin alignment and/or padding are set");
-                    return false;
-                }
-            }
-            return true;
+            return this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning);
         };
         };
         Prim2DBase.prototype._positioningDirty = function () {
         Prim2DBase.prototype._positioningDirty = function () {
             if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning)) {
             if (!this._isFlagSet(BABYLON.SmartPropertyPrim.flagUsePositioning)) {

File diff suppressed because it is too large
+ 8 - 8
dist/preview release/canvas2D/babylon.canvas2d.min.js