1週間でFlexファイラを作ろうプロジェクト 3日目
昨日に引き続き、3日目。
- ファイラウィンドウを別のmxmlファイルに分けた
- ウィンドウを複数作れるようなった
- ウィンドウがD&Dで移動できるようになった(ちょっと挙動不審)
- ウィンドウがドラッグしてリサイズできるようになった(もうちょっと挙動不審)
今日の変更はクライアント側(Flex側)だけです。
- FlexFile.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:ff="*" creationComplete="init()" layout="horizontal"> <mx:Script> <![CDATA[ public function addNewWindow(event:MouseEvent):void { var ffw:FlexFileWindow = new FlexFileWindow(); ffw.width = canvas.width/2; ffw.height = canvas.height/2; ffw.x = (canvas.width - ffw.width) / 2; ffw.y = (canvas.height - ffw.height) / 2; canvas.addChild(ffw); } ]]> </mx:Script> <mx:VBox height="100%"> <mx:Button label="add" click="addNewWindow(event)"/> </mx:VBox> <mx:Canvas width="100%" height="100%" id="canvas"> <!--<ff:FlexFileWindow/>--> <ff:FlexFileWindow width="60%" height="60%"/> </mx:Canvas> </mx:Application>
- FlexFileWindow.mxml
<?xml version="1.0" encoding="utf-8"?> <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml"> <mx:Panel width="100%" height="100%" creationComplete="init()" id="panel"> <mx:Script source="FlexFileWindow.as"/> <mx:DataGrid id="grid" width="100%" height="100%" doubleClickEnabled="true" doubleClick="onDoubleClickData(event)"> <mx:columns> <mx:DataGridColumn dataField="name" headerText="name" width="200"/> <mx:DataGridColumn dataField="size" headerText="size" width="100" textAlign="right" sortCompareFunction="sizeSortCompareFunction"/> <mx:DataGridColumn dataField="type" headerText="type" width="100" textAlign="right"/> </mx:columns> </mx:DataGrid> <mx:ControlBar> <mx:VBox width="100%"> <mx:HBox width="100%"> <mx:Label id="pathInput" width="100%"/> <!--<mx:TextInput id="pathInput" width="100%"/>--> <mx:Button label="Upload" click="onUpload(event)"/> </mx:HBox> <mx:TextArea width="100%" height="40" id="area"/> </mx:VBox> </mx:ControlBar> </mx:Panel> <mx:HTTPService id="fileService" showBusyCursor="true" result="onResult(event)" fault="onFault(event)" /> <mx:VBox backgroundColor="#eeee00" width="15" height="15" y="{height-15}" x="{width-15}" id="resizer"/> </mx:Canvas>
- FlexFileWindow.as
// vim:syntax=javascript import mx.controls.Alert; import mx.rpc.events.*; import mx.rpc.http.HTTPService; import mx.utils.ObjectUtil; import flash.net.FileReference; import mx.collections.ArrayCollection; import mx.utils.StringUtil; private var _resizing:Boolean; private var _serverURL:String; private var _currentPath:String; private var _uploadFile:FileReference; private var _downloadFile:FileReference; public function set title(str:String):void { panel.title = str; } private function init():void { _serverURL = "http://syuki.skr.jp/test/flex/flexfile_03.cgi"; fileService.url = _serverURL; this.title = _serverURL.replace(/^.+\:\/\//, "flexfile\:\/\/"); sendRequest("/"); _uploadFile = new FileReference(); _uploadFile.addEventListener(Event.SELECT, uploadFileSelected); _uploadFile.addEventListener(Event.COMPLETE, uploadFileComplete); _uploadFile.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadFileCompleteAndResponse); _uploadFile.addEventListener(IOErrorEvent.IO_ERROR, uploadIOError); _uploadFile.addEventListener(SecurityErrorEvent.SECURITY_ERROR, uploadSecurityError); _downloadFile = new FileReference(); _downloadFile.addEventListener(Event.SELECT, downloadFileSelected); _downloadFile.addEventListener(Event.COMPLETE, downloadFileComplete); _downloadFile.addEventListener(IOErrorEvent.IO_ERROR, downloadIOError); _downloadFile.addEventListener(SecurityErrorEvent.SECURITY_ERROR, downloadSecurityError); addEventListener(MouseEvent.MOUSE_DOWN, mouseDown); addEventListener(MouseEvent.MOUSE_UP, mouseReleased); //this.titleBar.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown); //this.titleBar.addEventListener(MouseEvent.MOUSE_UP, mouseReleased); _resizing = false; resizer.addEventListener(MouseEvent.MOUSE_DOWN, startResize); this.addEventListener(MouseEvent.MOUSE_MOVE, doResize); resizer.addEventListener(MouseEvent.MOUSE_UP, stopResize); } private function mouseDown(event:MouseEvent):void { this.startDrag(); parent.setChildIndex(this, parent.numChildren - 1); } private function mouseReleased(event:MouseEvent):void { stopDrag(); } private function startResize(event:MouseEvent):void { resizer.startDrag(); event.stopPropagation(); _resizing = true; } private function doResize(event:MouseEvent):void { if(_resizing) { this.width = resizer.x+15; this.height = resizer.y+15; } } private function stopResize(event:MouseEvent):void { _resizing = false; stopDrag(); resizer.x = this.width - 15; resizer.y = this.height - 15; } private function sendRequest(path:String):void { fileService.method = "GET"; fileService.request.command = "list"; fileService.request.path = path; fileService.send(); } private function refreshFileList(entries:Object):void { grid.dataProvider = entries; } private function onResult(e:ResultEvent):void { refreshFileList(fileService.lastResult.DirectoryEntryList.DirectoryEntries.entry); _currentPath = fileService.lastResult.DirectoryEntryList.path; pathInput.text = _currentPath; } private function onFault(e:FaultEvent):void { Alert.show(e.fault.faultString); } private function sizeSortCompareFunction(obj1:Object, obj2:Object):int { var num1:Number = obj1.size; var num2:Number = obj2.size; if( isNaN(num1) && isNaN(num2) ) { return 0; } else if( isNaN(num1) && !isNaN(num2) ) { return 1; } else if( !isNaN(num1) && isNaN(num2) ) { return -1; } else if( num1 < num2 ) { return 1; } else if( num1 > num2 ) { return -1; } return 0; } private function onDoubleClickData(event:MouseEvent):void { var item:Object = event.currentTarget.selectedItem; if( item.type == "directory" ) { area.text = "list: " + _currentPath + "/" + item.name; sendRequest( _currentPath + "/" + item.name ); } else { area.text = "download: " + _currentPath + "/" + item.name; var req:URLRequest = new URLRequest(fileService.url); req.method = URLRequestMethod.GET; var cmd:URLVariables = new URLVariables(); cmd.command = "download"; cmd.path = _currentPath + "/" + item.name; req.data = cmd; _downloadFile.download(req, item.name); } } private function onUpload(event:MouseEvent):void { _uploadFile.browse(); } private function uploadFileSelected(event:Event):void { var file:FileReference = FileReference(event.target); var req:URLRequest = new URLRequest(fileService.url); req.method = URLRequestMethod.GET; var cmd:URLVariables = new URLVariables(); cmd.command = "upload"; cmd.path = _currentPath; req.data = cmd; file.upload(req, "file"); } private function uploadFileComplete(event:Event):void { } private function uploadIOError(event:IOErrorEvent):void { Alert.show("Upload failed: " + event.target.name + ":\n" + event.text ); } private function uploadSecurityError(event:SecurityErrorEvent):void { Alert.show("Upload failed: " + event.target.name + ":\n" + event.text ); } private function uploadFileCompleteAndResponse(event:DataEvent):void { var xml:XML = XML(event.text.toString()); if( xml.name().localName == "QueryError" ) { Alert.show("Upload failed: " + event.target.name + ":\n" + xml.Message ); } else { Alert.show(event.target.name + " is successfully uploaded."); refreshFileList(xml.DirectoryEntries.entry); } } private function downloadFileSelected(event:Event):void { } private function downloadFileComplete(event:Event):void { //Alert.show(event.target.name + " is successfully downloaded."); } private function downloadIOError(event:IOErrorEvent):void { Alert.show("Download failed: " + event.target.name + ":\n" + event.text ); } private function downloadSecurityError(event:SecurityErrorEvent):void { Alert.show("Download failed: " + event.target.name + ":\n" + event.text ); }
ポイントは、startDrag()とstopDrag()。なんともお手軽なことに、ドラッグしたいインスタンスにstartDrag()を呼ぶだけでドラッグしてくれます。
resizer(右下の黄色い四角)は、ドラッグされているときにマウスイベント(MouseEvent.MOUSE_MOVE)を捕捉して、親のCanvasの大きさを変えています。これでドラッグしてリサイズを実現。
ただ、急激にウィンドウを大きくすると、親のCanvasにスクロールバーが出てしまって、大きさが変わらなくなってしまうという問題が。うーむ。どうしたものか…