forked from: 矩形選択ツール

by h_sakurai forked from 矩形選択ツール (diff: 149)
矩形選択ツールをもうちょっと使いやすく。

矩形を描いた後にドラッグやカーソルキーで
変形できる。

矩形選択ツールの部分以外は最低限の機能。

参考
http://iccii.seesaa.net/article/28058268.html

...
@author umhr
♥0 | Line 291 | Modified 2011-07-05 13:10:53 | MIT License
play

ActionScript3 source code

/**
 * Copyright h_sakurai ( http://wonderfl.net/user/h_sakurai )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/pv04
 */

// forked from umhr's 矩形選択ツール
/*
 * 矩形選択ツールをもうちょっと使いやすく。
 * 
 * 矩形を描いた後にドラッグやカーソルキーで
 * 変形できる。
 * 
 * 矩形選択ツールの部分以外は最低限の機能。
 * 
 * 参考
 * http://iccii.seesaa.net/article/28058268.html
 * */

package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.display.*;
    import flash.net.*;
    
        
    import com.bit101.components.PushButton;
    /**
     * ...
     * @author umhr
     */
    [SWF(backgroundColor="0x777777")]
    public class Main extends Sprite 
    {
        private var _highlite:Highlite;
        private var _canvas:Sprite;
        private var _bitmap:Bitmap;
        public function Main():void 
        {
            stage.scaleMode = "noScale";
            stage.align = "TL";
     
            
            //矩形選択ツール
            _highlite = new Highlite(0,0,400,400);
            var loader:Loader = new Loader();
            var obj:Object = loaderInfo.parameters;
            loader.load(new URLRequest(obj['url']), null);
            
            addChild(loader);
            addChild(_highlite);
            tf.y = 400;
            tf.height = 20;
            tf.text = obj['url'];
            addChild(tf);
            
        }
        
    }
}

import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.utils.Dictionary;
import flash.text.*;


var tf:TextField  = new TextField();

class Highlite extends Sprite {
    private var _in:Point;
    private var _rectangle:Rectangle;
    public var selectedRectangle:Rectangle;
    private var _selectedArea:SelectedArea;
    public var onChange:Function = function(selectedRectangle:Rectangle):void{};
    public function Highlite(x:Number=0,y:Number=0,width:Number=0,height:Number=0){
        _in = new Point();
        rectangle = new Rectangle(x, y, width, height);
        selectedRectangle = new Rectangle();
        _selectedArea = new SelectedArea();
        this.addChild(_selectedArea);
        this.addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        this.addEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage);
    }
    private function onAddedToStage(event:Event):void {
        this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        stage.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
        stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
    }
    private function onRemoveFromStage(event:Event):void {
        this.removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
        this.removeEventListener(Event.REMOVED_FROM_STAGE, onRemoveFromStage);
        stage.removeEventListener(MouseEvent.MOUSE_DOWN, onDown);
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
        stage.removeEventListener(MouseEvent.MOUSE_UP, onUp);
        stage.removeEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
    }
    
    //矢印キーで選択域を移動できる。
    private function onKeyDown(event:KeyboardEvent):void {
        if (_selectedArea.selected < 0) { return };
        var keyObj:Object = { 37:[ -1, 0], 38:[0, -1], 39:[1, 0], 40:[0, 1] };
        if (keyObj[event.keyCode]) {
            //if (!isNaN(_selectedArea.dictionary[stage.focus]) && _selectedArea.dictionary[stage.focus] < 9) {
                //var selected:int = _selectedArea.dictionary[stage.focus];
            if (_selectedArea.selected < 9) {
                var selected:int = _selectedArea.selected;
                var pointTL:Point = selectedRectangle.topLeft;
                var pointBR:Point = selectedRectangle.bottomRight;
                if (selected == 4) {
                    pointTL.x += keyObj[event.keyCode][0];
                    pointBR.x += keyObj[event.keyCode][0];
                }else if(selected%3 == 0){
                    pointTL.x += keyObj[event.keyCode][0];
                }else if(selected%3 == 2){
                    pointBR.x += keyObj[event.keyCode][0];
                }
                if (selected == 4) {
                    pointTL.y += keyObj[event.keyCode][1];
                    pointBR.y += keyObj[event.keyCode][1];
                }else if(selected <= 2){
                    pointTL.y += keyObj[event.keyCode][1];
                }else if(selected >= 6){
                    pointBR.y += keyObj[event.keyCode][1];
                }
                target(pointTL, pointBR);
            }
        }
        //trace(event.keyCode, stage.focus, _selectedArea.dictionary[stage.focus],keyObj[event.keyCode])
    }
    
    private function target(a:Point, b:Point):void {
        var x:Number = Math.max(0, Math.min(a.x, b.x));
        var y:Number = Math.max(0, Math.min(a.y, b.y));
        var w:Number = Math.min(rectangle.width, Math.max(a.x, b.x)) - x;
        var h:Number = Math.min(rectangle.height, Math.max(a.y, b.y)) - y;
        if (w < 0 || h < 0) { return };
        this.graphics.clear();
        this.graphics.beginFill(0xCC3333,0.5);
        this.graphics.drawRect(0, 0, rectangle.width, rectangle.height);
        this.graphics.drawRect(x, y, w, h);
        _selectedArea.setSize(x, y, w, h);
        this.graphics.endFill();
        selectedRectangle = new Rectangle(x, y, w, h);
        onChange(selectedRectangle);
    }
     public function set rectangle(rect:Rectangle):void{
        this.x = rect.x;
        this.y = rect.y;
        _rectangle = rect;
    }
    public function get rectangle():Rectangle{
        return _rectangle;
    }
    private var _isUp:Boolean;
    private function onUp(event:MouseEvent):void {
        _isUp = true;
    }
    private function onDown(event:MouseEvent):void {
        if (_selectedArea.dictionary[event.target] == undefined || !_isUp) {
            _isUp = false;
            _in = new Point(this.mouseX, this.mouseY);
            _selectedArea.selected = -1;
        }else if (!isNaN(_selectedArea.dictionary[event.target])) {
            _selectedArea.handlePoint = new Point(this.mouseX, this.mouseY);
            _selectedArea.selected = _selectedArea.dictionary[event.target];
        }
    }
    
    //マウスドラッグ時
    private function onMove(event:MouseEvent):void {
        _selectedArea.isMouseOver = selectedRectangle.contains(this.mouseX, this.mouseY);
        if (!event.buttonDown) { return };
        if (_selectedArea.dictionary[event.target] == undefined && !_isUp) {
            //選択域を作る
            target(_in, new Point(this.mouseX, this.mouseY));
        }else if (_selectedArea.selected > -1) {
            //選択域をドラッグする
            var selected:int = _selectedArea.selected;
            if (selected == 100) { return };
            var subtract:Point = _selectedArea.handlePoint.subtract(new Point(this.mouseX, this.mouseY));
            var pointTL:Point = selectedRectangle.topLeft;
            var pointBR:Point = selectedRectangle.bottomRight;
            if (selected == 4) {
                pointTL.x -= subtract.x;
                pointBR.x -= subtract.x;
            }else if(selected%3 == 0){
                pointTL.x -= subtract.x;
            }else if(selected%3 == 2){
                pointBR.x -= subtract.x;
            }
            if (selected == 4) {
                pointTL.y -= subtract.y;
                pointBR.y -= subtract.y;
            }else if(selected <= 2){
                pointTL.y -= subtract.y;
            }else if(selected >= 6){
                pointBR.y -= subtract.y;
            }
            target(pointTL, pointBR);
            _selectedArea.handlePoint = new Point(this.mouseX, this.mouseY);
        }
    }
}


class SelectedArea extends Sprite {
    public var handlePoint:Point;
    public var selected:int;
    private var _handles:Array;
    public var dictionary:Dictionary;
    private var _handleWidth:int;
    private var _handleHeight:int;
    private var _isMouseOver:Boolean;
    
    public function SelectedArea() {
        super();
        dictionary = new Dictionary();
        dictionary[this] = 100;
        handlePoint = new Point();
        selected = -1;
        _handles = [];
        for (var i:int = 0; i < 9; i++) {
            _handles[i] = new Sprite();
            this.addChild(_handles[i]);
            dictionary[_handles[i]] = i;
        }
    }
    //ハンドルを設置
    private function setHandleGraphics(width:int, height:int):void {
        if ((_handleWidth == width && _handleHeight == height) && _isMouseOver) {
            return;
        }
        for (var i:int = 0; i < 9; i++) {
            _handles[i].graphics.clear();
            _handles[i].graphics.beginFill(0xCCCCCC, 0);
            _handles[i].graphics.drawRect(0,0,width,height);
            _handles[i].graphics.endFill();
            
            _handles[i].graphics.lineStyle(1, 0x666666);
            if(i == 0){
                _handles[i].graphics.moveTo(0, height);
                _handles[i].graphics.lineTo(width, height);
                _handles[i].graphics.lineTo(width, 0);
            }else if(i == 1){
                _handles[i].graphics.moveTo(0, 0);
                _handles[i].graphics.lineTo(0, height);
                _handles[i].graphics.lineTo(width, height);
                _handles[i].graphics.lineTo(width, 0);
            }else if(i == 2){
                _handles[i].graphics.moveTo(0, 0);
                _handles[i].graphics.lineTo(0, height);
                _handles[i].graphics.lineTo(width, height);
            }else if(i == 3){
                _handles[i].graphics.moveTo(0,0);
                _handles[i].graphics.lineTo(width, 0);
                _handles[i].graphics.lineTo(width, height);
                _handles[i].graphics.lineTo(0,height);
            }else if(i == 4){
                _handles[i].graphics.moveTo(0,0);
                _handles[i].graphics.lineTo(0, height);
                _handles[i].graphics.lineTo(width, height);
                _handles[i].graphics.lineTo(width, 0);
                _handles[i].graphics.lineTo(0, 0);
            }else if(i == 5){
                _handles[i].graphics.moveTo(width, height);
                _handles[i].graphics.lineTo(0,height);
                _handles[i].graphics.lineTo(0, 0);
                _handles[i].graphics.lineTo(width,0);
            }else if(i == 6){
                _handles[i].graphics.moveTo(0, 0);
                _handles[i].graphics.lineTo(width,0);
                _handles[i].graphics.lineTo(width, height);
            }else if(i == 7){
                _handles[i].graphics.moveTo(0, height);
                _handles[i].graphics.lineTo(0, 0);
                _handles[i].graphics.lineTo(width,0);
                _handles[i].graphics.lineTo(width, height);
            }else if(i == 8){
                _handles[i].graphics.moveTo(0, height);
                _handles[i].graphics.lineTo(0, 0);
                _handles[i].graphics.lineTo(width,0);
            }
        }
        _handleWidth = width;
        _handleHeight = height;
    }
    //マウスオーバー時ハンドル表示
    public function set isMouseOver(isOver:Boolean):void {
        if (_isMouseOver == isOver) {
            if (isOver || _handleWidth*_handleHeight == 0) {
                return;
            }
        };
        if (isOver) {
            setHandleGraphics(_handleWidth, _handleHeight);
        }else {
            for (var i:int = 0; i < 9; i++) {
                _handles[i].graphics.clear();
            }
        }
        _isMouseOver = isOver;
    }
    //ハンドルの位置を調整
    public function setSize(x:int, y:int, width:int, height:int):void {
        tf.text ="("+x+","+y+" "+width+","+height+")";
        
        this.x = x;
        this.y = y;
        //透明のエリアがあることによって、選択域の中のハンドルがない部分があることを検地させる
        this.graphics.clear();
        this.graphics.beginFill(0x000000,0);
        this.graphics.drawRect(0, 0, width, height);
        this.graphics.endFill();
        
        var w:int = Math.floor(Math.min(width / 4, 20));
        var h:int = Math.floor(Math.min(height / 4, 20));
        setHandleGraphics(w, h);
        
        _handles[1].x = (width - _handles[1].width) / 2;
        _handles[2].x = width - _handles[2].width+1;
        
        _handles[3].y = (height - _handles[3].height) / 2;
        _handles[4].x = (width - _handles[4].width) / 2;
        _handles[4].y = (height - _handles[4].height) / 2;
        _handles[5].x = width - _handles[5].width+1;
        _handles[5].y = (height - _handles[5].height) / 2;
        
        _handles[6].y = (height - _handles[6].height)+1;
        _handles[7].x = (width - _handles[7].width) / 2;
        _handles[7].y = (height - _handles[7].height) +1;
        _handles[8].x = width - _handles[8].width+1;
        _handles[8].y = (height - _handles[8].height)+1;
    }
}