root/as3/DepthManager/src/com/voidelement/manager/DepthManager.as

リビジョン 132, 6.1 kB (コミッタ: yossy, コミット時期: 4 年 前)

Moved.

  • svn:mime-type 属性の設定値: text/plain;charset=utf-8
Line 
1 /**
2  * com.voidelement.manager.DepthManager  Class for ActionScript 3.0
3  * 
4  * @author       Copyright (c) 2007 munegon
5  * @version      1.0
6  * 
7  * @link         http://www.voidelement.com/
8  * @link         http://void.heteml.jp/blog/
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  * 
14  * http://www.apache.org/licenses/LICENSE-2.0
15  * 
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
19  * either express or implied. See the License for the specific language
20  * governing permissions and limitations under the License.
21  */
22
23
24
25
26 package com.voidelement.manager {
27         import flash.display.DisplayObject;
28         import flash.display.DisplayObjectContainer;
29         import flash.utils.Dictionary;
30        
31        
32         public class DepthManager {
33                 private const DEPTH_RESERVED:int = 1048575;
34                 private const DEPTH_HIGHEST :int = 2130690045;
35                 private const DEPTH_LOWEST  :int = -16383;
36                
37                 private var _container:DisplayObjectContainer;
38                 private var _dict:Dictionary;
39                
40                
41                 /**
42                  * コンストラクタ
43                  *
44                  * @param base 進度を管理するDisplayObjectContainer
45                  */
46                 public function DepthManager( container:DisplayObjectContainer ):void {
47                         _container = container;
48                         _dict = new Dictionary( true );
49                        
50                         var len:int = _container.numChildren;
51                         var child:DisplayObject;
52                        
53                         for ( var i:int = 0; i < len; ++i ){
54                                 child = _container.getChildAt( i );
55                                 _dict[ i ] = child;
56                                 _dict[ child ] = i;
57                         }
58
59                 }
60                
61                
62                 /**
63                  * 末尾に子を追加する
64                  *
65                  * @param child 追加するDisplayObject
66                  */
67                 public function addChild( child:DisplayObject ):DisplayObject {
68                         var depth:int = _container.numChildren ? _dict[ _container.getChildAt( _container.numChildren - 1 ) ] + 1 : 0;
69                        
70                         _dict[ depth ] = child;
71                         _dict[ child ] = depth;
72                        
73                         return _container.addChild( child );
74                 }
75                
76                
77                 /**
78                  * 指定した深度に子を追加する
79                  *
80                  * @param child 追加するDisplayObject
81                  * @param depth 追加先深度
82                  */
83                 public function addChildAt( child:DisplayObject, depth:int ):DisplayObject {
84                         var index:int = searchIndex( depth );
85                        
86                         if ( index < _container.numChildren ){
87                                 var child0:DisplayObject = _container.getChildAt( index );
88                                
89                                 if ( _dict[ child0 ] == depth ){
90                                         // 指定深度に先客がいる場合は削除
91                                         removeChild( child0 );
92                                 }
93                         }
94                        
95                         _dict[ depth ] = child;
96                         _dict[ child ] = depth;
97                        
98                         return _container.addChildAt( child, index );
99                 }
100                
101                
102                 /**
103                  * 指定した深度へ子を移動させる
104                  *
105                  * @param child 移動するDisplayObject
106                  * @param depth 移動先深度
107                  */
108                 public function setDepth( child:DisplayObject, depth:int ):void {
109                         if ( ( depth < DEPTH_LOWEST ) || ( depth > DEPTH_HIGHEST ) ){
110                                 throw( new Error("Caution: " + depth + " is over limit of depth") );
111                         }
112                         if ( _dict[ child ] == depth ){
113                                 return;
114                         }
115                        
116                         var child0:DisplayObject = getInstanceAtDepth( depth );
117                        
118                         if ( child0 != null ){
119                                 // 指定深度に先客がいる場合は交換
120                                 swapChildren( child, child0 );
121                         } else {
122                                 var index:int = searchIndex( depth );
123                                
124                                 delete _dict[ _dict[ child ] ];
125                                 _dict[ child ] = depth;
126                                 _dict[ depth ] = child;
127                                
128                                 if ( _container.getChildIndex( child ) < index ){
129                                         _container.setChildIndex( child, index - 1 );
130                                 } else {
131                                         _container.setChildIndex( child, index );
132                                 }
133                         }
134                 }
135                
136                
137                 /**
138                  * 指定した子の深度を取得する
139                  */
140                 public function getDepth( child:DisplayObject ):int {
141                         return _dict[ child ];
142                 }
143                
144                
145                 /**
146                  * 子を交換する
147                  */
148                 public function swapChildren( child1:DisplayObject, child2:DisplayObject ):void {
149                         if ( child1 == child2 ){
150                                 return;
151                         }
152                        
153                         var depth:int = _dict[ child1 ];
154                         _dict[ child1 ] = _dict[ child2 ];
155                         _dict[ child2 ] = depth;
156                        
157                         _dict[ _dict[ child1 ] ] = child1;
158                         _dict[ _dict[ child2 ] ] = child2;
159                        
160                         _container.swapChildren( child1, child2 );
161                 }
162                
163                
164                 /**
165                  * 指定した子を削除する
166                  *
167                  * @param child 削除するDisplayObject
168                  */
169                 public function removeChild( child:DisplayObject ):DisplayObject {
170                         delete _dict[ _dict[ child ] ];
171                         delete _dict[ child ];
172                        
173                         return _container.removeChild( child );
174                 }
175                
176                
177                 /**
178                  * 指定深度の子を削除する
179                  *
180                  * @param depth 削除指定深度
181                  */
182                 public function removeChildAt( depth:int ):DisplayObject {
183                         var child:DisplayObject = _dict[ depth ];
184                        
185                         if ( child == null ){
186                                 throw( new RangeError("Caution: no child at depth " + depth ) );
187                         }
188                        
189                         delete _dict[ child ];
190                         delete _dict[ depth ];
191                        
192                         return _container.removeChild( child );
193                 }
194                
195                 /**
196                  * 指定深度に該当する子のインデックスを返す
197                  */
198                 private function searchIndex( depth:int ):int {
199                         if ( _container.numChildren > 0 ){
200                                 var left:int = 0;
201                                 var right:int = _container.numChildren - 1;
202                                 var index:int = right;
203                                 var child:DisplayObject = _container.getChildAt( index );
204                                
205                                 if ( depth <= _dict[ _container.getChildAt( 0 ) ] ){
206                                         return 0;
207                                 }
208                                 if ( _dict[ child ] < depth ){
209                                         return index + 1;
210                                 }
211                                
212                                 while ( _dict[ child ] != depth ){
213                                         if ( index == left ){
214                                                 index += ( _dict[ child ] < depth ) ? 1 : 0;
215                                                 break;
216                                         } else if ( depth < _dict[ child ] ){
217                                                 right = index;
218                                                 index = ( left + right ) >> 1;
219                                         } else if ( _dict[ child ] < depth ){
220                                                 left = index;
221                                                 index = ( left + right ) >> 1;
222                                         } else {
223                                                 break;
224                                         }
225                                        
226                                         child = _container.getChildAt( index );
227                                 }
228                                
229                                 return index;
230                         } else {
231                                 return 0;
232                         }
233                 }
234                
235                 /**
236                  *  指定深度に配置されているインスタンスを取得する
237                  */
238                 private function getInstanceAtDepth( depth:int ):DisplayObject {
239                         return _dict[ depth ];
240                 }
241         }
242 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。