崖っぷちの男

たぶん技術っぽいネタ。ブログ名が決められない

Flexで画面上の複数のオブジェクトをドラッグして選択するアレを使いたい

と思って探したら、こちらで紹介されていたのでありがたく使わせていただきました。英語では「Marching Ants(アリの行列)」っていうんですね。


Marching ants selection marquee in Flex « Very Interactive People


解説の後に「download it here」というリンクがあって、サンプルソースがダウンロードできます。


ちなみに使ってみたところ、MarchingAntsSelectionRectangle オブジェクトはどこに置いてもいい訳ではないみたいです。ルートの子の位置に置けば表示されますが、ルートの孫の位置だと表示されませんでした。ここらへん Flex がまだよく分かっていないので分かる人には当たり前のことなのかも。。

縦スクロールに対応するには

他のページを紹介して終わるのもアレなのでこちらのソースの改造ネタを。
元のソースだと縦に長い画面で縦スクロールバーが出てて、しかも下にスクロールしているときに問題が起きます。選択時の四角い点線が思った位置に描画されません。
これはスクロール位置を計算してないためで、下のように四角の y 座標に「verticalScrollPosition」を足すとうまくいきます。

        private function  startSelectionDrawing_handler(evt:MouseEvent):void{
                selectionRect=new Rectangle();
                selectionRect.x=mouseX;
                selectionRect.y=mouseY + verticalScrollPosition;
                selectionRect.width=1;
                selectionRect.height=1;
                addEventListener(Event.ENTER_FRAME,updateSelection_handler);
        }

	private function updateSelection_handler(evt:Event):void{
		selectionRect.width=mouseX-selectionRect.x;
		selectionRect.height=mouseY + verticalScrollPosition -selectionRect.y;
		marchingAntsSelectionRect.rect=selectionRect;
	}


また「startSelectionDrawing_handler」については、実際は他の MouseEvent.MOUSE_DOWN と競合しないように、event.target が特定のクラスの時だけ実行するようにしています。これは他にもっといいやり方があるのかもしれません。

            private function  startSelectionDrawing_handler(evt:MouseEvent):void{
			if (event.target is FlexLoader || event.target is Canvas) {
				// 略
			}
            }

シフトキーを押しながら選択もやりたい

selectItems() を selectItems(event:MouseEvent) に変えておけば、この関数の中で event.shiftKey を使えます。これを使ってシフトキーを押していたときとそうでないときで処理を変えます。
具体的にはシフトキーを押していない場合、全てのオブジェクトを未選択の状態にするという処理を入れておけばいいです。

特定のオブジェクトの子供だけを選択できるようにする

例えば someArea というオブジェクトがあって、この子供以下を選択できるようにしたかったのですが、次のようにするとうまくいきました。なぜ「getRect(someArea.parent)」なのかはよく分かりません。教えてエロ。

                for (var i:Number=0;i<someArea.numChildren;i++){
                        if(selectionRect.intersects(someArea.getChildAt(i).getRect(someArea.parent))){
                            someArea.getChildAt(i).filters=[new GlowFilter(0x33FF33,1,3,3,4,1)];
                        }else{
                            someArea.getChildAt(i).filters=[];
                        }
                }




「闘うプログラマー」上巻を最近読み終わりました。仕事に役立つかどうかは微妙ですが読んでいておもしろいです。
主人公がスポーツ万能で硬派な感じのプログラマーというのもなんか新鮮です。昔、プログラマーといえば女性だった頃もあったという話とか、知らないことが出てきてびっくりしました。