チェンジセット 1870

差分発生行の前後
無視リスト:
コミット日時:
2008/11/18 12:18:08 (2 ヶ月前)
コミッタ:
taiga
ログメッセージ:

初期化時の不具合、キーフォーカス処理の不具合を修正

ファイル:

凡例:

変更無し
追加
削除
更新
コピー
移動
  • as3/TigerBibliotheken/trunk/TigerBibliotheken/src/jp/taiga/flex3/component/containers/ImageDragger.as

    r1838 r1870  
    2222    import mx.core.Container; 
    2323    import mx.core.UIComponent; 
    24     import mx.events.FlexEvent; 
    2524    import mx.managers.IFocusManagerComponent; 
    2625    /** 
    27      * ImageDragger 
     26     * <p>ImageDragger クラスは、画像を読み込み、読み込んだ画像上に MXML タグでネストした UIComponent を配置し、マウスドラッグ操作やマウスホイールによる拡大縮小操作を行う Container サブクラスです。</p> 
    2827     * @author taiga 
    2928     */ 
    3029    public class ImageDragger extends Container implements IFocusManagerComponent { 
    31         private var _base              :UIComponent; 
    32         private var _mask              :UIComponent; 
    33         private var _loader            :Loader; 
    34         private var _tmpMouseX         :Number; 
    35         private var _tmpMouseY         :Number; 
    36         private var _tmpUnscaledWidth  :Number; 
    37         private var _tmpUnscaledHeight :Number; 
    38         private var _nowImageWidth     :Number; 
    39         private var _nowImageHeight    :Number; 
    40         private var _oldImageWidth     :Number = 0; 
    41         private var _oldImageHeight    :Number = 0; 
    42         private var _childLength       :int    = 0; 
    43         private var _minPercentScale   :int    = 50; 
    44         private var _maxPercentScale   :int    = 70; 
    45         private var _nowPercentScale   :int    = 100; 
    46         private var _isDragMove        :Boolean; 
    47         private var _isKeyFocus        :Boolean; 
    48         private var _source            :String; 
    49         /** scale(%) */ 
    50         public function get percentScale():int          { return _nowPercentScale; } 
    51         /** @param */ 
    52         public function set percentScale(v:int):void    { _nowPercentScale = v; } 
     30        private var _base                  :UIComponent; 
     31        private var _mask                  :UIComponent; 
     32        private var _loader                :Loader; 
     33        private var _childDescriptors      :Array; 
     34        private var _tmpMouseX             :Number; 
     35        private var _tmpMouseY             :Number; 
     36        private var _tmpUnscaledWidth      :Number; 
     37        private var _tmpUnscaledHeight     :Number; 
     38        private var _nowImageWidth         :Number; 
     39        private var _nowImageHeight        :Number; 
     40        private var _oldImageWidth         :Number; 
     41        private var _oldImageHeight        :Number; 
     42        private var _childrenFocusPosition :int; 
     43        private var _minPercentScale       :int; 
     44        private var _maxPercentScale       :int; 
     45        private var _nowPercentScale       :int; 
     46        private var _defaultPercentScale   :int; 
     47        private var _startPercentScale     :int; 
     48        private var _isDragMove            :Boolean; 
     49        private var _isKeyFocus            :Boolean; 
     50        private var _source                :String; 
     51        /** defaultPercentScale(%) */ 
     52        public function set defaultPercentScale(v:int):void { _defaultPercentScale = v; } 
    5353        /** image.x */ 
    54         public function get imageX():int                { return _base.x; } 
    55         /** @param */ 
    56         public function set imageX(v:int):void          { _base.x = v; } 
     54        public function get imageX():int                    { return _base.x; } 
     55        /** @private */ 
     56        public function set imageX(v:int):void              { _base.x = v; } 
    5757        /** image.y */ 
    58         public function get imageY():int                { return _base.y; } 
    59         /** @param */ 
    60         public function set imageY(v:int):void          { _base.y = v; } 
     58        public function get imageY():int                    { return _base.y; } 
     59        /** @private */ 
     60        public function set imageY(v:int):void              { _base.y = v; } 
    6161        /** image.width */ 
    62         public function get imageWidth():int            { return _nowImageWidth; } 
     62        public function get imageWidth():int                { return _nowImageWidth; } 
    6363        /** max percent scale */ 
    64         public function set maxPercentScale(v:int):void { _maxPercentScale = v; } 
    65         /** min percent scale */ 
    66         public function set minPercentScale(v:int):void { _minPercentScale = v; } 
     64        public function set maxPercentScale(v:int):void     { _maxPercentScale = v; } 
     65        /** min percent scale (for defaultPercentScale) */ 
     66        public function set minPercentScale(v:int):void     { _minPercentScale = v; } 
    6767        /** image URL */ 
    68         public function set source(s:String):void       { _source = s; } 
     68        public function set source(s:String):void           { _source = s; } 
    6969        /** 
    7070         * constructor 
     71         * @private 
     72         * コンストラクタ 
    7173         */ 
    7274        public function ImageDragger() { 
     
    7577            super.tabEnabled        = true; 
    7678            super.mouseFocusEnabled = true; 
    77         } 
    78         /** 
    79          * @inheritDoc 
     79            _childDescriptors       = []; 
     80            _oldImageWidth          = 0; 
     81            _oldImageHeight         = 0; 
     82            _childrenFocusPosition  = 0; 
     83            _nowPercentScale        = 100; 
     84        } 
     85        /** 
     86         * @inheritDoc 
     87         * @private 
     88         * 子要素の生成 
    8089         */ 
    8190        protected override function createChildren():void { 
    82             _base   = new UIComponent(); 
     91            _base = new UIComponent(); 
     92            _base.addEventListener(FocusEvent.FOCUS_IN,    function(e:FocusEvent):void { e.stopImmediatePropagation(); }, true, 0, true); 
     93            _base.addEventListener(FocusEvent.FOCUS_OUT,   function(e:FocusEvent):void { e.stopImmediatePropagation(); }, true, 0, true); 
     94            _base.addEventListener(FocusEvent.FOCUS_IN,    function(e:FocusEvent):void { e.stopImmediatePropagation(); }, false, 0, true); 
     95            _base.addEventListener(FocusEvent.FOCUS_OUT,   function(e:FocusEvent):void { e.stopImmediatePropagation(); }, false, 0, true); 
     96            _base.addEventListener(MouseEvent.MOUSE_DOWN,  mouseDownHandler,  false, 0, true); 
     97            _base.addEventListener(MouseEvent.MOUSE_UP,    mouseUpHandler,    false, 0, true); 
     98            _base.addEventListener(MouseEvent.MOUSE_MOVE,  mouseMoveHandler,  false, 0, true); 
     99            _base.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler, false, 0, true); 
    83100            addChild(_base); 
    84101 
    85             _mask   = new UIComponent(); 
     102            _mask = new UIComponent(); 
    86103            addChild(_mask); 
    87104 
    88105            _loader = new Loader(); 
     106            _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler, false, 0, true); 
    89107            _base.addChild(_loader); 
    90108 
     
    97115        /** 
    98116         * @inheritDoc 
    99          */ 
    100         public override function addChild(child:DisplayObject):DisplayObject { 
    101             if(child == _base || child == _mask) { 
    102                 return super.addChild(child); 
    103             } 
    104             return _base.addChild(child as DisplayObject); 
    105         } 
    106         /** 
    107          * @inheritDoc 
     117         * @private 
     118         * 初期化完了後画像を読み込む 
     119         * TODO:任意のタイミングで画像の差し替えを行えるようにする 
    108120         */ 
    109121        protected override function initializationComplete():void { 
    110122            super.initializationComplete(); 
    111  
    112             addEventListener(FocusEvent.KEY_FOCUS_CHANGE, keyFocusChangeHandler, false, 0, true); 
    113             addEventListener(Event.ENTER_FRAME,           enterFrameHandler,     false, 0, true); 
    114             systemManager.stage.addEventListener(MouseEvent.MOUSE_UP,   dragStopHandler,  false, 0, true); 
    115             systemManager.stage.addEventListener(MouseEvent.ROLL_OUT,   dragStopHandler,  false, 0, true); 
    116             systemManager.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, false, 0, true); 
    117             _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadCompleteHandler, false, 0, true); 
    118123            _loader.load(new URLRequest(_source)); 
    119124        } 
    120125        /** 
    121126         * @inheritDoc 
     127         * @private 
     128         * 描画更新、マスク領域の再構築 
    122129         */ 
    123130        protected override function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { 
     
    130137            _tmpUnscaledHeight = unscaledHeight; 
    131138 
    132             with (_mask.graphics) { //マスク領域再構築 
     139            with (_mask.graphics) { 
     140                //マスク領域再構築 
    133141                clear(); 
    134142                beginFill(0x000000); 
     
    140148        /** 
    141149         * @inheritDoc 
     150         * @private 
     151         * 子コントロールに関しては、コンテナに addChild() させず、_base にて addChild() を実行する 
     152         */ 
     153        public override function addChild(child:DisplayObject):DisplayObject { 
     154            if(child == _base || child == _mask) { 
     155                return super.addChild(child); 
     156            } 
     157            _childDescriptors.push(child); 
     158            child.addEventListener(FocusEvent.FOCUS_OUT, childFocusOutHandler); 
     159            child.visible = false; 
     160            return _base.addChild(child); 
     161        } 
     162        /** 
     163         * @inheritDoc 
     164         * @private 
     165         * 子コントロールに関しては、コンテナに removeChild() させず、_base に対して removeChild() を実行する 
     166         */ 
     167        public override function removeChild(child:DisplayObject):DisplayObject { 
     168            if(child == _base || child == _mask) { 
     169                return super.removeChild(child); 
     170            } 
     171            _childDescriptors.some( function(item:*, index:int, array:Array):Boolean { 
     172                                        if(item == child) { 
     173                                            array.splice(index, 1); 
     174                                            return true; 
     175                                        } 
     176                                        else { 
     177                                            return false; 
     178                                        } 
     179                                    }, child ); 
     180            child.removeEventListener(FocusEvent.FOCUS_OUT, childFocusOutHandler); 
     181            return _base.removeChild(child); 
     182        } 
     183        /** 
     184         * @inheritDoc 
    142185         */ 
    143186        protected override function focusInHandler(event:FocusEvent):void { 
    144             super.focusInHandler(event); 
     187            if(event.eventPhase != EventPhase.AT_TARGET) { 
     188                return; 
     189            } 
     190            var max:int = _childDescriptors.length - 1; 
    145191            if(null != super.focusManager) { 
    146                 super.focusManager.showFocus(); 
    147             } 
    148         } 
    149         /** 
    150          * @inheritDoc 
    151          */ 
    152         protected override function focusOutHandler(event:FocusEvent):void { 
    153             //TODO:仕様の見直し 
    154             super.focusOutHandler(event); 
    155             if(!_isKeyFocus) 
     192                if(event.shiftKey) { 
     193                    UIComponent(_childDescriptors[max]).setFocus(); 
     194                    _childrenFocusPosition = max; 
     195                } 
     196                else { 
     197                    UIComponent(_childDescriptors[0]).setFocus(); 
     198                    _childrenFocusPosition = 0; 
     199                } 
     200            } 
     201        } 
     202        /** 
     203         * @inheritDoc 
     204         */ 
     205        protected override function focusOutHandler(event:FocusEvent):void {} 
     206        /** 
     207         * dragImage load complete 
     208         * @private 
     209         * イメージの読み込み完了イベント 
     210         * TODO:任意のタイミングで読み込みできるように変更したとき、全面的に修正する。 
     211         */ 
     212        private function loadCompleteHandler(event:Event):void { 
     213            var i:int; 
     214            var tempComponent:UIComponent; 
     215 
     216            _loader.scaleX   = _defaultPercentScale * 0.01; 
     217            _loader.scaleY   = _defaultPercentScale * 0.01; 
     218            _nowImageWidth   = _defaultPercentScale * 0.01 * _loader.contentLoaderInfo.width; 
     219            _nowImageHeight  = _defaultPercentScale * 0.01 * _loader.contentLoaderInfo.height; 
     220            _minPercentScale = (_minPercentScale != 0) ? _minPercentScale : 50; 
     221            _maxPercentScale = (_maxPercentScale != 0) ? _maxPercentScale : 150; 
     222 
     223            for(i = 0; i < _childDescriptors.length; i++) { 
     224                tempComponent = _childDescriptors[i] as UIComponent; 
     225                tempComponent.visible = true; 
     226            } 
     227 
     228            addEventListener(Event.ENTER_FRAME, enterFrameHandler, false, 0, true); 
     229            systemManager.stage.addEventListener(MouseEvent.MOUSE_UP,   dragStopHandler,  false, 0, true); 
     230            systemManager.stage.addEventListener(MouseEvent.ROLL_OUT,   dragStopHandler,  false, 0, true); 
     231            systemManager.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, false, 0, true); 
     232 
     233            _loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, arguments.callee, false); 
     234        } 
     235        /** 
     236         * children focusOut Event 
     237         * @private 
     238         * 子コントロールの FOCUS_OUT イベント 
     239         */ 
     240        private function childFocusOutHandler(event:FocusEvent):void { 
     241            if(!_base.contains(event.currentTarget as DisplayObject)) { 
     242                event.stopImmediatePropagation(); 
    156243                return; 
    157             _childLength = (!event.shiftKey) ? _childLength + 1 : _childLength - 1; 
    158             if(1 > _childLength) { 
    159                 _childLength = 0; 
    160                 _isKeyFocus = false; 
    161                 return; 
    162             } 
    163             else if(_base.numChildren - 2 < _childLength) { 
    164                 _childLength = (!event.shiftKey) ? 0 : _childLength - 1; 
    165                 _isKeyFocus = false; 
    166                 return; 
    167             } 
    168             if(null != _base.getChildAt(_childLength) ) { 
    169                 UIComponent(_base.getChildAt(_childLength)).setFocus(); 
    170             } 
    171             _isKeyFocus = false; 
    172         } 
    173         /** 
    174          * key focus change 
    175          */ 
    176         private function keyFocusChangeHandler(event:FocusEvent):void { 
    177             _isKeyFocus = true; 
    178         } 
    179         /** 
    180          * image load complete 
    181          */ 
    182         private function loadCompleteHandler(event:Event):void { 
    183             _base.addEventListener(MouseEvent.MOUSE_DOWN,  mouseDownHandler,  false, 0, true); 
    184             _base.addEventListener(MouseEvent.MOUSE_UP,    mouseUpHandler,    false, 0, true); 
    185             _base.addEventListener(MouseEvent.MOUSE_MOVE,  mouseMoveHandler,  false, 0, true); 
    186             _base.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelHandler, false, 0, true); 
    187             _nowImageWidth   = _loader.width; 
    188             _nowImageHeight  = _loader.height; 
    189             _loader.scaleX   = _nowPercentScale * 0.01; 
    190             _loader.scaleY   = _nowPercentScale * 0.01; 
    191             _nowPercentScale = 100; 
    192             _loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, arguments.callee, false); 
    193         } 
     244            } 
     245 
     246            if(event.shiftKey) { 
     247                if(--_childrenFocusPosition < 0) { 
     248                    dispatchEvent(event); 
     249                } 
     250                else { 
     251                    _childDescriptors[_childrenFocusPosition].setFocus(); 
     252                } 
     253            } 
     254            else { 
     255                if(++_childrenFocusPosition >= _childDescriptors.length) { 
     256                    dispatchEvent(event); 
     257                } 
     258                else { 
     259                    _childDescriptors[_childrenFocusPosition].setFocus(); 
     260                } 
     261            } 
     262        } 
     263 
    194264        /** 
    195265         * startDrag 
     266         * @private 
     267         * ドラッグ開始処理 
    196268         */ 
    197269        private function mouseDownHandler(event:MouseEvent):void { 
     
    202274        /** 
    203275         * dragging 
     276         * @private 
     277         * ドラッグ処理 
    204278         */ 
    205279        private function mouseMoveHandler(event:MouseEvent):void { 
     
    207281                return; 
    208282            } 
     283 
    209284            var dx     :Number = mouseX  - _tmpMouseX; 
    210285            var dy     :Number = mouseY  - _tmpMouseY; 
    211286            var evalDX :Number = _base.x + dx; 
    212287            var evalDY :Number = _base.y + dy; 
    213             var minDX  :Number = width  - _nowImageWidth; 
    214             var minDY  :Number = height - _nowImageHeight; 
     288            var minDX  :Number = unscaledWidth  - _nowImageWidth; 
     289            var minDY  :Number = unscaledHeight - _nowImageHeight; 
     290 
    215291            if(0 < evalDX) { 
    216292                evalDX = 0; 
     
    225301                evalDY = (height < _nowImageHeight) ? minDY : 0; 
    226302            } 
     303 
    227304            _base.move(evalDX, evalDY); 
    228305            _tmpMouseX = mouseX; 
    229306            _tmpMouseY = mouseY; 
     307 
    230308            event.updateAfterEvent(); 
     309 
    231310        } 
    232311        /** 
    233312         * stopDrag 
     313         * @private 
     314         * ドラッグ停止処理 
    234315         */ 
    235316        private function mouseUpHandler(event:MouseEvent):void { 
     
    238319        /** 
    239320         * stage's stopDrag 
     321         * @private 
     322         * ドラッグ停止処理 
    240323         */ 
    241324        private function dragStopHandler(event:MouseEvent):void { 
     
    244327        /** 
    245328         * mouse wheel 
     329         * @private 
     330         * ホイール処理 
     331         * TODO:Mac 対応 
    246332         */ 
    247333        private function mouseWheelHandler(event:MouseEvent):void { 
     334 
    248335            if(_isDragMove) { 
    249336                return; 
    250337            } 
     338 
    251339            var dx         :Number; 
    252340            var dy         :Number; 
    253341            var deltaValue :int = event.delta / 2; 
     342 
    254343            _nowPercentScale += deltaValue; 
     344 
    255345            if(_nowImageWidth && _nowImageHeight) { 
    256346                _oldImageWidth    = _nowImageWidth; 
     
    261351                _oldImageHeight   = _loader.height; 
    262352            } 
    263             if(_minPercentScale  >= _nowPercentScale) { //最小縮小値 
     353 
     354 
     355            if(_minPercentScale  >= _nowPercentScale) { 
     356                //最小縮小値 
    264357                _nowPercentScale  = _minPercentScale; 
    265358            } 
    266             else if(_maxPercentScale < _nowPercentScale){ //最大拡大値 
     359            else if(_maxPercentScale < _nowPercentScale){ 
     360                //最大拡大値 
    267361                _nowPercentScale = _maxPercentScale - Math.abs(deltaValue); 
    268362            } 
     
    272366            _nowImageHeight = _nowPercentScale * 0.01 * _loader.height; 
    273367 
    274             if(0 > deltaValue) { //_delta が負の数のとき 
     368            if(0 > deltaValue) { 
     369                //_delta が負の数のとき 
    275370                dx = (_oldImageWidth  - _nowImageWidth)  / 2; 
    276371                dy = (_oldImageHeight - _nowImageHeight) / 2; 
     
    278373                _base.y += dy; 
    279374            } 
    280             else {//_delta が正の数のとき 
     375            else { 
     376                //_delta が正の数のとき 
    281377                dx = (_nowImageWidth  - _oldImageWidth)  / 2; 
    282378                dy = (_nowImageHeight - _oldImageHeight) / 2; 
     
    287383        } 
    288384        /** 
    289          * draw update 
     385         * coordinate correction 
     386         * @private 
     387         * 座標補正 
    290388         */ 
    291389        private function enterFrameHandler(evevnt:Event):void {