UNPKG

dragonbones-runtime

Version:

the tools to build dragonbones file for diffrent framework

909 lines (830 loc) 25.9 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. // ////////////////////////////////////////////////////////////////////////////////////// /// <reference path="../states/State.ts" /> /// <reference path="../core/UIComponent.ts" /> /// <reference path="../utils/registerProperty.ts" /> namespace eui { /** * @private */ const enum Keys{ contentWidth, contentHeight, scrollH, scrollV, scrollEnabled, touchThrough } /** * The Group class is defines the base class for layout component. * If the contents of the sub items are too large to scroll to show, you can wrap a Scroller component outside the * group (Give the instance of Group to <code>viewport</code> property of Scroller component). * The scroller component can adds a scrolling touch operation for the Group. * * @see http://edn.egret.com/cn/article/index/id/608 Simple container * @defaultProperty elementsContent * @includeExample extension/eui/components/GroupExample.ts * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * Group 是自动布局的容器基类。如果包含的子项内容太大需要滚动显示,可以在在 Group 外部包裹一层 Scroller 组件 * (将 Group 实例赋值给 Scroller 组件的 viewport 属性)。Scroller 会为 Group 添加滚动的触摸操作功能,并显示垂直或水平的滚动条。 * * @see http://edn.egret.com/cn/article/index/id/608 简单容器 * @defaultProperty elementsContent * @includeExample extension/eui/components/GroupExample.ts * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ export class Group extends egret.DisplayObjectContainer implements IViewport { /** * Constructor. * * @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 */ public constructor() { super(); this.initializeUIValues(); this.$Group = { 0: 0, //contentWidth, 1: 0, //contentHeight, 2: 0, //scrollH, 3: 0, //scrollV, 4: false, //scrollEnabled, 5: false, //touchThrough }; this.$stateValues.parent = this; } $Group:Object; /** * This property is Usually invoked in resolving an EXML for adding multiple children quickly. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 此属性通常在 EXML 的解析器中调用,便于快速添加多个子项。 * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public set elementsContent(value:egret.DisplayObject[]) { if (value) { let length = value.length; for (let i = 0; i < length; i++) { this.addChild(value[i]); } } } /** * @private */ $layout:LayoutBase = null; /** * The layout object for this container. * This object is responsible for the measurement and layout of * the UIcomponent in the container. * * @default eui.BasicLayout * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 此容器的布局对象。 * * s@default eui.BasicLayout * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get layout():LayoutBase { return this.$layout; } public set layout(value:LayoutBase) { this.$setLayout(value); } /** * @private * * @param value */ $setLayout(value:LayoutBase):boolean { if (this.$layout == value) return false; if (this.$layout) { this.$layout.target = null; } this.$layout = value; if (value) { value.target = this; } this.invalidateSize(); this.invalidateDisplayList(); return true; } /** * @copy eui.IViewport#contentWidth * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public get contentWidth():number { return this.$Group[Keys.contentWidth]; } /** * @copy eui.IViewport#contentHeight * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public get contentHeight():number { return this.$Group[Keys.contentHeight]; } /** * * Sets the <code>contentWidth</code> and <code>contentHeight</code> * properties. * * This method is intended for layout class developers who should * call it from <code>updateDisplayList()</code> methods. * * @param width The new value of <code>contentWidth</code>. * @param height The new value of <code>contentHeight</code>. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * * 设置 <code>contentWidth</code> 和 <code>contentHeight</code> 属性。 * 此方法由布局来调用,开发者应该在布局类的 <code>updateDisplayList()</code> 方法中对其进行调用。 * * @param width <code>contentWidth</code> 的新值。 * @param height <code>contentHeight</code> 的新值。 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public setContentSize(width:number, height:number):void { width = Math.ceil(+width || 0); height = Math.ceil(+height || 0); let values = this.$Group; let wChange = (values[Keys.contentWidth] !== width); let hChange = (values[Keys.contentHeight] !== height); if (!wChange && !hChange) { return; } values[Keys.contentWidth] = width; values[Keys.contentHeight] = height; if (wChange) { PropertyEvent.dispatchPropertyEvent(this, PropertyEvent.PROPERTY_CHANGE, "contentWidth"); } if (hChange) { PropertyEvent.dispatchPropertyEvent(this, PropertyEvent.PROPERTY_CHANGE, "contentHeight"); } } /** * @copy eui.IViewport#scrollEnabled * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public get scrollEnabled():boolean { return this.$Group[Keys.scrollEnabled]; } public set scrollEnabled(value:boolean) { value = !!value; let values = this.$Group; if (value === values[Keys.scrollEnabled]) return; values[Keys.scrollEnabled] = value; this.updateScrollRect(); } /** * @copy eui.IViewport#scrollH * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public get scrollH():number { return this.$Group[Keys.scrollH]; } public set scrollH(value:number) { value = +value || 0; let values = this.$Group; if (value === values[Keys.scrollH]) return; values[Keys.scrollH] = value; if (this.updateScrollRect() && this.$layout) { this.$layout.scrollPositionChanged(); } PropertyEvent.dispatchPropertyEvent(this, PropertyEvent.PROPERTY_CHANGE, "scrollH"); } /** * @copy eui.IViewport#scrollV * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public get scrollV():number { return this.$Group[Keys.scrollV]; } public set scrollV(value:number) { value = +value || 0; let values = this.$Group; if (value == values[Keys.scrollV]) return; values[Keys.scrollV] = value; if (this.updateScrollRect() && this.$layout) { this.$layout.scrollPositionChanged(); } PropertyEvent.dispatchPropertyEvent(this, PropertyEvent.PROPERTY_CHANGE, "scrollV"); } /** * @private * * @returns */ private updateScrollRect():boolean { let values = this.$Group; let hasClip = values[Keys.scrollEnabled]; if (hasClip) { let uiValues = this.$UIComponent; this.scrollRect = egret.$TempRectangle.setTo(values[Keys.scrollH], values[Keys.scrollV], uiValues[sys.UIKeys.width], uiValues[sys.UIKeys.height]); } else if (this.$scrollRect) { this.scrollRect = null; } return hasClip; } /** * The number of layout element in this container. * * @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 */ public get numElements():number { return this.$children.length; } /** * Returns the layout element at the specified index. * * @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 */ public getElementAt(index:number):egret.DisplayObject { return this.$children[index]; } public getVirtualElementAt(index:number):egret.DisplayObject{ return this.getElementAt(index); } /** * Set the index range of the sub Visual element in container which support virtual layout. * This method is invalid in container which do not support virtual layout. * This method is usually invoked before layout. Override this method to release the invisible elements. * * @param startIndex the start index of sub visual elements(include) * @param endIndex the end index of sub visual elements(include) * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 在支持虚拟布局的容器中,设置容器内可见的子元素索引范围。此方法在不支持虚拟布局的容器中无效。 * 通常在即将重新布局子项之前会被调用一次,容器覆盖此方法提前释放已经不可见的子元素。 * * @param startIndex 可视元素起始索引(包括) * @param endIndex 可视元素结束索引(包括) * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public setVirtualElementIndicesInView(startIndex:number, endIndex:number):void { } /** * When <code>true</code>, this property * ensures that the entire bounds of the Group respond to * touch events such as begin. * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language en_US */ /** * 触摸组件的背景透明区域是否可以穿透。设置为true表示可以穿透,反之透明区域也会响应触摸事件。默认 false。 * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native * @language zh_CN */ public get touchThrough():boolean{ return this.$Group[Keys.touchThrough]; } public set touchThrough(value:boolean){ this.$Group[Keys.touchThrough] = !!value; } /** * @private */ $hitTest(stageX:number, stageY:number):egret.DisplayObject { let target = super.$hitTest(stageX, stageY); if (target || this.$Group[Keys.touchThrough]) { return target; } if (!this.$visible || !this.touchEnabled) { return null; } let point = this.globalToLocal(stageX, stageY, egret.$TempPoint); let values = this.$UIComponent; let bounds = egret.$TempRectangle.setTo(0, 0, values[sys.UIKeys.width], values[sys.UIKeys.height]); let scrollRect = this.$scrollRect; if(scrollRect){ bounds.x = scrollRect.x; bounds.y = scrollRect.y; } if (bounds.contains(point.x, point.y)) { return this; } return null; } /** * @private */ $stateValues:sys.StateValues = new sys.StateValues(); /** * The list of state for this component. * * @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 */ public states:State[]; /** * @copy eui.Component#currentState * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public currentState:string; /** * @copy eui.Skin#hasState() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public hasState:(stateName:string)=>boolean; /** * @private * 初始化所有视图状态 */ private initializeStates:(stage:egret.Stage)=>void; /** * @private * 应用当前的视图状态。子类覆盖此方法在视图状态发生改变时执行相应更新操作。 */ private commitCurrentState:()=>void; /** * @copy eui.Component#invalidateState() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public invalidateState():void { let values = this.$stateValues; if (values.stateIsDirty) { return; } values.stateIsDirty = true; this.invalidateProperties(); } /** * @copy eui.Component#getCurrentState() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ protected getCurrentState():string { return ""; } //=======================UIComponent接口实现=========================== /** * @private * UIComponentImpl 定义的所有变量请不要添加任何初始值,必须统一在此处初始化。 */ private initializeUIValues:()=>void; /** * @copy eui.Component#createChildren() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ protected createChildren():void { if (!this.$layout) { this.$setLayout(new BasicLayout()); } this.initializeStates(this.$stage); } /** * @copy eui.Component#childrenCreated() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ protected childrenCreated():void { } /** * @copy eui.Component#commitProperties() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ protected commitProperties():void { sys.UIComponentImpl.prototype["commitProperties"].call(this); let values = this.$stateValues; if (values.stateIsDirty) { values.stateIsDirty = false; if (!values.explicitState) { values.currentState = this.getCurrentState(); this.commitCurrentState(); } } } /** * @copy eui.Component#measure() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ protected measure():void { if (!this.$layout) { this.setMeasuredSize(0, 0); return; } this.$layout.measure(); } /** * @copy eui.Component#updateDisplayList() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ protected updateDisplayList(unscaledWidth:number, unscaledHeight:number):void { if (this.$layout) { this.$layout.updateDisplayList(unscaledWidth, unscaledHeight); } this.updateScrollRect(); } /** * @copy eui.Component#invalidateParentLayout() * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ protected invalidateParentLayout():void { } /** * @private */ $UIComponent:Object; /** * @private */ $includeInLayout:boolean; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public includeInLayout:boolean; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public left:any; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public right:any; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public top:any; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public bottom:any; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public horizontalCenter:any; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public verticalCenter:any; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public percentWidth:number; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public percentHeight:number; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public explicitWidth:number; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public explicitHeight:number; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public minWidth:number; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public maxWidth:number; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public minHeight:number; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public maxHeight:number; /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public setMeasuredSize(width:number, height:number):void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public invalidateProperties():void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public validateProperties():void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public invalidateSize():void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public validateSize(recursive?:boolean):void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public invalidateDisplayList():void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public validateDisplayList():void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public validateNow():void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public setLayoutBoundsSize(layoutWidth:number, layoutHeight:number):void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public setLayoutBoundsPosition(x:number, y:number):void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public getLayoutBounds(bounds:egret.Rectangle):void { } /** * @inheritDoc * * @version Egret 2.4 * @version eui 1.0 * @platform Web,Native */ public getPreferredBounds(bounds:egret.Rectangle):void { } } sys.implementUIComponent(Group, egret.DisplayObjectContainer, true); sys.mixin(Group, sys.StateClient); registerProperty(Group, "elementsContent", "Array", true); registerProperty(Group, "states", "State[]"); }