///
module BABYLON.GUI {
/** Class used to render 2D lines */
export class Line extends Control {
private _lineWidth = 1;
private _x1 = new ValueAndUnit(0);
private _y1 = new ValueAndUnit(0);
private _x2 = new ValueAndUnit(0);
private _y2 = new ValueAndUnit(0);
private _dash = new Array();
private _connectedControl: Control;
private _connectedControlDirtyObserver: Nullable>;
/** Gets or sets the dash pattern */
public get dash(): Array {
return this._dash;
}
public set dash(value: Array) {
if (this._dash === value) {
return;
}
this._dash = value;
this._markAsDirty();
}
/** Gets or sets the control connected with the line end */
public get connectedControl(): Control {
return this._connectedControl;
}
public set connectedControl(value: Control) {
if (this._connectedControl === value) {
return;
}
if (this._connectedControlDirtyObserver && this._connectedControl) {
this._connectedControl.onDirtyObservable.remove(this._connectedControlDirtyObserver);
this._connectedControlDirtyObserver = null;
}
if (value) {
this._connectedControlDirtyObserver = value.onDirtyObservable.add(() => this._markAsDirty());
}
this._connectedControl = value;
this._markAsDirty();
}
/** Gets or sets start coordinates on X axis */
public get x1(): string | number {
return this._x1.toString(this._host);
}
public set x1(value: string | number ) {
if (this._x1.toString(this._host) === value) {
return;
}
if (this._x1.fromString(value)) {
this._markAsDirty();
}
}
/** Gets or sets start coordinates on Y axis */
public get y1(): string | number {
return this._y1.toString(this._host);
}
public set y1(value: string | number ) {
if (this._y1.toString(this._host) === value) {
return;
}
if (this._y1.fromString(value)) {
this._markAsDirty();
}
}
/** Gets or sets end coordinates on X axis */
public get x2(): string | number {
return this._x2.toString(this._host);
}
public set x2(value: string | number ) {
if (this._x2.toString(this._host) === value) {
return;
}
if (this._x2.fromString(value)) {
this._markAsDirty();
}
}
/** Gets or sets end coordinates on Y axis */
public get y2(): string | number {
return this._y2.toString(this._host);
}
public set y2(value: string | number ) {
if (this._y2.toString(this._host) === value) {
return;
}
if (this._y2.fromString(value)) {
this._markAsDirty();
}
}
/** Gets or sets line width */
public get lineWidth(): number {
return this._lineWidth;
}
public set lineWidth(value: number) {
if (this._lineWidth === value) {
return;
}
this._lineWidth = value;
this._markAsDirty();
}
/** Gets or sets horizontal alignment */
public set horizontalAlignment(value: number) {
return;
}
/** Gets or sets vertical alignment */
public set verticalAlignment(value: number) {
return;
}
private get _effectiveX2(): number {
return (this._connectedControl ? this._connectedControl.centerX : 0) + this._x2.getValue(this._host);
}
private get _effectiveY2(): number {
return (this._connectedControl ? this._connectedControl.centerY : 0) + this._y2.getValue(this._host);
}
/**
* Creates a new Line
* @param name defines the control name
*/
constructor(public name?: string) {
super(name);
this.isHitTestVisible = false;
this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
}
protected _getTypeName(): string {
return "Line";
}
public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
context.save();
if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
context.shadowColor = this.shadowColor;
context.shadowBlur = this.shadowBlur;
context.shadowOffsetX = this.shadowOffsetX;
context.shadowOffsetY = this.shadowOffsetY;
}
this._applyStates(context);
if (this._processMeasures(parentMeasure, context)) {
context.strokeStyle = this.color;
context.lineWidth = this._lineWidth;
context.setLineDash(this._dash);
context.beginPath();
context.moveTo(this._x1.getValue(this._host), this._y1.getValue(this._host));
context.lineTo(this._effectiveX2, this._effectiveY2);
context.stroke();
}
context.restore();
}
public _measure(): void {
// Width / Height
this._currentMeasure.width = Math.abs(this._x1.getValue(this._host) - this._effectiveX2) + this._lineWidth;
this._currentMeasure.height = Math.abs(this._y1.getValue(this._host) - this._effectiveY2) + this._lineWidth;
}
protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
this._currentMeasure.left = Math.min(this._x1.getValue(this._host), this._effectiveX2) - this._lineWidth / 2;
this._currentMeasure.top = Math.min(this._y1.getValue(this._host), this._effectiveY2) - this._lineWidth / 2;
}
/**
* Move one end of the line given 3D cartesian coordinates.
* @param position Targeted world position
* @param scene Scene
* @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
*/
public moveToVector3(position: Vector3, scene: Scene, end: boolean = false): void {
if (!this._host || this._root !== this._host._rootContainer) {
Tools.Error("Cannot move a control to a vector3 if the control is not at root level");
return;
}
var globalViewport = this._host._getGlobalViewport(scene);
var projectedPosition = Vector3.Project(position, Matrix.Identity(), scene.getTransformMatrix(), globalViewport);
this._moveToProjectedPosition(projectedPosition, end)
if (projectedPosition.z < 0 || projectedPosition.z > 1) {
this.notRenderable = true;
return;
}
this.notRenderable = false;
}
/**
* Move one end of the line to a position in screen absolute space.
* @param projectedPosition Position in screen absolute space (X, Y)
* @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
*/
public _moveToProjectedPosition(projectedPosition: Vector3, end: boolean = false): void {
let x: string = (projectedPosition.x + this._linkOffsetX.getValue(this._host)) + "px";
let y: string = (projectedPosition.y + this._linkOffsetY.getValue(this._host)) + "px";
if (end) {
this.x2 = x;
this.y2 = y;
this._x2.ignoreAdaptiveScaling = true;
this._y2.ignoreAdaptiveScaling = true;
} else {
this.x1 = x;
this.y1 = y;
this._x1.ignoreAdaptiveScaling = true;
this._y1.ignoreAdaptiveScaling = true;
}
}
}
}