UNPKG

dragonbones-runtime

Version:

the tools to build dragonbones file for diffrent framework

853 lines (774 loc) 24.1 kB
////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2014-present, Egret Technology. // All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of the Egret nor the // names of its contributors may be used to endorse or promote products // derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA, // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ////////////////////////////////////////////////////////////////////////////////////// namespace eui { /** * Linear layout base class, usually as the parent class of * <code>HorizontalLayout</code> and <code>VerticalLayout</code>. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 线性布局基类,通常作为 <code>HorizontalLayout</code> 和 <code>VerticalLayout</code> 的父类。 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ export class LinearLayoutBase extends LayoutBase { /** * @private */ $horizontalAlign:string = "left"; /** * The horizontal alignment of layout elements. * <p>The <code>egret.HorizontalAlign</code> and <code>eui.JustifyAlign</code> class * defines the possible values for this property.</p> * * @default "left" * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 布局元素的水平对齐策略。 * <p><code>egret.HorizontalAlign</code> 和 * <code>eui.JustifyAlign</code>类定义此属性的可能值。<p> * * @default "left" * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get horizontalAlign():string { return this.$horizontalAlign; } public set horizontalAlign(value:string) { if (this.$horizontalAlign == value) return; this.$horizontalAlign = value; if (this.$target) this.$target.invalidateDisplayList(); } /** * @private */ $verticalAlign:string = "top"; /** * The vertical alignment of layout elements. * <p>The <code>egret.VerticalAlign</code> and <code>eui.JustifyAlign</code> class * defines the possible values for this property.</p> * * @default "top" * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 布局元素的垂直对齐策略。请使用 VerticalAlign 定义的常量。 * <p><code>egret.VerticalAlign</code> 和 * <code>eui.JustifyAlign</code>类定义此属性的可能值。<p> * * @default "top" * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get verticalAlign():string { return this.$verticalAlign; } public set verticalAlign(value:string) { if (this.$verticalAlign == value) return; this.$verticalAlign = value; if (this.$target) this.$target.invalidateDisplayList(); } /** * @private */ $gap:number = 6; /** * The space between layout elements, in pixels. * * @default 6 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 布局元素之间的间隔(以像素为单位)。 * * @default 6 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get gap():number { return this.$gap; } public set gap(value:number) { value = +value || 0; if (this.$gap === value) return; this.$gap = value; this.invalidateTargetLayout(); } /** * @private */ $paddingLeft:number = 0; /** * Number of pixels between the container's left edge * and the left edge of the first layout element. * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 容器的左边缘与第一个布局元素的左边缘之间的像素数。 * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get paddingLeft():number { return this.$paddingLeft; } public set paddingLeft(value:number) { value = +value || 0; if (this.$paddingLeft === value) return; this.$paddingLeft = value; this.invalidateTargetLayout(); } /** * @private */ $paddingRight:number = 0; /** * Number of pixels between the container's right edge * and the right edge of the last layout element. * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 容器的右边缘与最后一个布局元素的右边缘之间的像素数。 * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get paddingRight():number { return this.$paddingRight; } public set paddingRight(value:number) { value = +value || 0; if (this.$paddingRight === value) return; this.$paddingRight = value; this.invalidateTargetLayout(); } /** * @private */ $paddingTop:number = 0; /** * The minimum number of pixels between the container's top edge and * the top of all the container's layout elements. * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 容器的顶边缘与所有容器的布局元素的顶边缘之间的最少像素数。 * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get paddingTop():number { return this.$paddingTop; } public set paddingTop(value:number) { value = +value || 0; if (this.$paddingTop === value) return; this.$paddingTop = value; this.invalidateTargetLayout(); } /** * @private */ $paddingBottom:number = 0; /** * The minimum number of pixels between the container's bottom edge and * the bottom of all the container's layout elements. * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 容器的底边缘与所有容器的布局元素的底边缘之间的最少像素数。 * * @default 0 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get paddingBottom():number { return this.$paddingBottom; } public set paddingBottom(value:number) { value = +value || 0; if (this.$paddingBottom === value) return; this.$paddingBottom = value; this.invalidateTargetLayout(); } /** * Convenience function for subclasses that invalidates the * target's size and displayList so that both layout's <code>measure()</code> * and <code>updateDisplayList</code> methods get called. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 失效目标容器的尺寸和显示列表的简便方法,调用目标容器的 * <code>measure()</code>和<code>updateDisplayList</code>方法 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected invalidateTargetLayout():void { let target = this.$target; if (target) { target.invalidateSize(); target.invalidateDisplayList(); } } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public measure():void { if (!this.$target) return; if (this.$useVirtualLayout) { this.measureVirtual(); } else { this.measureReal(); } } /** * Compute exact values for measuredWidth and measuredHeight. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 计算目标容器 measuredWidth 和 measuredHeight 的精确值 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected measureReal():void { } /** * Compute potentially approximate values for measuredWidth and measuredHeight. * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 计算目标容器 measuredWidth 和 measuredHeight 的近似值 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected measureVirtual():void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public updateDisplayList(width:number, height:number):void { let target = this.$target; if (!target) return; if (target.numElements == 0) { target.setContentSize(Math.ceil(this.$paddingLeft + this.$paddingRight), Math.ceil(this.$paddingTop + this.$paddingBottom)); return; } if (this.$useVirtualLayout) { this.updateDisplayListVirtual(width, height); } else { this.updateDisplayListReal(width, height); } } /** * An Array of the virtual layout elements size cache. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 虚拟布局使用的尺寸缓存。 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected elementSizeTable:number[] = []; /** * Gets the starting position of the specified index element * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 获取指定索引元素的起始位置 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected getStartPosition(index:number):number { return 0; } /** * Gets the size of the specified index element * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 获取指定索引元素的尺寸 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected getElementSize(index:number):number { return 0; } /** * Gets the sum of the size of cached elements * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 获取缓存的子对象尺寸总和 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected getElementTotalSize():number { return 0; } /** * @inheritDoc * * @param index * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public elementRemoved(index:number):void { if (!this.$useVirtualLayout) return; super.elementRemoved(index); this.elementSizeTable.splice(index, 1); } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public clearVirtualLayoutCache():void { if (!this.$useVirtualLayout) return; this.elementSizeTable = []; this.maxElementSize = 0; } /** * The binary search to find the specified index position of the display object * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 折半查找法寻找指定位置的显示对象索引 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected findIndexAt(x:number, i0:number, i1:number):number { let index = ((i0 + i1) * 0.5)|0; let elementX = this.getStartPosition(index); let elementWidth = this.getElementSize(index); if ((x >= elementX) && (x < elementX + elementWidth + this.$gap)) return index; else if (i0 == i1) return -1; else if (x < elementX) return this.findIndexAt(x, i0, Math.max(i0, index - 1)); else return this.findIndexAt(x, Math.min(index + 1, i1), i1); } /** * The first element index in the view of the virtual layout * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 虚拟布局使用的当前视图中的第一个元素索引 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected startIndex:number = -1; /** * The last element index in the view of the virtual layout * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 虚拟布局使用的当前视图中的最后一个元素的索引 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected endIndex:number = -1; /** * A Flag of the first element and the end element has been calculated. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 视图的第一个和最后一个元素的索引值已经计算好的标志 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected indexInViewCalculated:boolean = false; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public scrollPositionChanged():void { super.scrollPositionChanged(); if (this.$useVirtualLayout) { let changed = this.getIndexInView(); if (changed) { this.indexInViewCalculated = true; this.target.invalidateDisplayList(); } } } /** * Get the index of the first and last element in the view, * and to return whether or not to change. * * @return has the index changed * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 获取视图中第一个和最后一个元素的索引,返回是否发生改变。 * * @return 索引是否已改变 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected getIndexInView():boolean { return false; } /** * The maximum size of elements * * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 子元素最大的尺寸 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected maxElementSize:number = 0; /** * Update the layout of the virtualized elements * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 更新虚拟布局的显示列表 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected updateDisplayListVirtual(width:number, height:number):void { } /** * Update the layout of the reality elements * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 更新真实布局的显示列表 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected updateDisplayListReal(width:number, height:number):void { } /** * Allocate blank area for each variable size element. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 为每个可变尺寸的子项分配空白区域。 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ protected flexChildrenProportionally(spaceForChildren:number, spaceToDistribute:number, totalPercent:number, childInfoArray:any[]):void { let numElements:number = childInfoArray.length; let done:boolean; do { done = true; let unused:number = spaceToDistribute - (spaceForChildren * totalPercent / 100); if (unused > 0) spaceToDistribute -= unused; else unused = 0; let spacePerPercent:number = spaceToDistribute / totalPercent; for (let i:number = 0; i < numElements; i++) { let childInfo:sys.ChildInfo = childInfoArray[i]; let size:number = childInfo.percent * spacePerPercent; if (size < childInfo.min) { let min:number = childInfo.min; childInfo.size = min; childInfoArray[i] = childInfoArray[--numElements]; childInfoArray[numElements] = childInfo; totalPercent -= childInfo.percent; if (unused >= min) { unused -= min; } else { spaceToDistribute -= min - unused; unused = 0; } done = false; break; } else if (size > childInfo.max) { let max:number = childInfo.max; childInfo.size = max; childInfoArray[i] = childInfoArray[--numElements]; childInfoArray[numElements] = childInfo; totalPercent -= childInfo.percent; if (unused >= max) { unused -= max; } else { spaceToDistribute -= max - unused; unused = 0; } done = false; break; } else { childInfo.size = size; } } } while (!done); } } } namespace eui.sys { /** * @private */ export class ChildInfo { /** * @private */ public layoutElement:eui.UIComponent = null; /** * @private */ public size:number = 0; /** * @private */ public percent:number = NaN; /** * @private */ public min:number = NaN; /** * @private */ public max:number = NaN; } }