├── README.md
├── key.p12
├── libs
├── puremvc.swc
├── bellonalib.swc
└── Windows8UIStyle.swc
├── SpaceSnifferAnywhere.air
├── screenCapture
├── QQ截图20140217170619.png
├── QQ截图20140217170815.png
├── QQ截图20140217170908.png
└── QQ截图20140217170945.png
├── tmp
└── Components2(TransitionStyle).swc
├── src
├── Global.as
├── org
│ └── marz
│ │ ├── sys
│ │ ├── CmdSys.as
│ │ ├── worker
│ │ │ ├── InitWorker.as
│ │ │ ├── WorkerSide.as
│ │ │ └── MainSide.as
│ │ ├── Init.as
│ │ └── OnEnterFrame.as
│ │ └── spaceSniffer
│ │ ├── c
│ │ ├── Refresh.as
│ │ ├── InitWorkSpaceUI.as
│ │ └── ExploreFileTree.as
│ │ ├── worker
│ │ ├── LaunchScan.as
│ │ └── WorkerReady.as
│ │ ├── m
│ │ ├── GridsProxy.as
│ │ └── vo
│ │ │ └── FileTree.as
│ │ └── v
│ │ ├── PickVolumeMediator.as
│ │ ├── GridsMediator.as
│ │ └── vo
│ │ └── GridRenderer.as
├── StartupProxy.as
├── SpaceSniffer.as
├── Startup.as
└── SpaceSniffer-app.xml
├── .gitignore
├── .project
└── .actionScriptProperties
/README.md:
--------------------------------------------------------------------------------
1 | SpaceSniffer
2 | ============
3 | 跨平台的SpaceSniffer
4 |
--------------------------------------------------------------------------------
/key.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/key.p12
--------------------------------------------------------------------------------
/libs/puremvc.swc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/libs/puremvc.swc
--------------------------------------------------------------------------------
/libs/bellonalib.swc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/libs/bellonalib.swc
--------------------------------------------------------------------------------
/SpaceSnifferAnywhere.air:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/SpaceSnifferAnywhere.air
--------------------------------------------------------------------------------
/libs/Windows8UIStyle.swc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/libs/Windows8UIStyle.swc
--------------------------------------------------------------------------------
/screenCapture/QQ截图20140217170619.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/screenCapture/QQ截图20140217170619.png
--------------------------------------------------------------------------------
/screenCapture/QQ截图20140217170815.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/screenCapture/QQ截图20140217170815.png
--------------------------------------------------------------------------------
/screenCapture/QQ截图20140217170908.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/screenCapture/QQ截图20140217170908.png
--------------------------------------------------------------------------------
/screenCapture/QQ截图20140217170945.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/screenCapture/QQ截图20140217170945.png
--------------------------------------------------------------------------------
/tmp/Components2(TransitionStyle).swc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/marzwu/SpaceSniffer/HEAD/tmp/Components2(TransitionStyle).swc
--------------------------------------------------------------------------------
/src/Global.as:
--------------------------------------------------------------------------------
1 | package
2 | {
3 | import flash.display.Stage;
4 |
5 | public class Global
6 | {
7 | public static var stage:Stage;
8 |
9 | public function Global()
10 | {
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/src/org/marz/sys/CmdSys.as:
--------------------------------------------------------------------------------
1 | package org.marz.sys
2 | {
3 | public class CmdSys
4 | {
5 | public static const ENTER_FRAME:String = 'enterFrame';
6 |
7 | public function CmdSys()
8 | {
9 | ENTER_FRAME
10 | }
11 | }
12 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build and Release Folders
2 | bin/
3 | bin-debug/
4 | bin-release/
5 |
6 | # Other files and folders
7 | .settings/
8 |
9 | # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
10 | # should NOT be excluded as they contain compiler settings and other important
11 | # information for Eclipse / Flash Builder.
12 |
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/c/Refresh.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.c
2 | {
3 | import org.marz.spaceSniffer.v.GridsMediator;
4 | import org.puremvc.as3.patterns.facade.Facade;
5 |
6 | public class Refresh
7 | {
8 | public function Refresh()
9 | {
10 | }
11 |
12 | public static function doRefresh():void
13 | {
14 | Facade.getInstance().sendNotification(GridsMediator.UPDATE);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/src/org/marz/sys/worker/InitWorker.as:
--------------------------------------------------------------------------------
1 | package org.marz.sys.worker
2 | {
3 | import org.puremvc.as3.interfaces.INotification;
4 | import org.puremvc.as3.patterns.command.SimpleCommand;
5 |
6 | public class InitWorker extends SimpleCommand
7 | {
8 | override public function execute(notification:INotification):void
9 | {
10 | // TODO Auto Generated method stub
11 | super.execute(notification);
12 | }
13 |
14 | }
15 | }
--------------------------------------------------------------------------------
/src/StartupProxy.as:
--------------------------------------------------------------------------------
1 | package
2 | {
3 | import flash.display.Stage;
4 |
5 | import org.puremvc.as3.patterns.facade.Facade;
6 | import org.puremvc.as3.patterns.proxy.Proxy;
7 |
8 | public class StartupProxy extends Proxy
9 | {
10 | private static const NAME:String = 'StartupProxy';
11 |
12 | public function StartupProxy()
13 | {
14 | super(NAME, null);
15 | }
16 |
17 | public static function get instance():StartupProxy
18 | {
19 | return StartupProxy(Facade.getInstance().retrieveProxy(NAME));
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/worker/LaunchScan.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.worker
2 | {
3 | import flash.filesystem.File;
4 |
5 | import org.marz.spaceSniffer.m.vo.FileTree;
6 | import org.marz.sys.worker.WorkerSide;
7 |
8 | public class LaunchScan
9 | {
10 | public function LaunchScan()
11 | {
12 | }
13 |
14 | public static function launch(args:Array):void
15 | {
16 | var b:File = new File;
17 | var file:File = new File(args[0]);
18 | var ft:FileTree = new FileTree(file);
19 | WorkerSide.instance.sendMsg('update',ft);
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/worker/WorkerReady.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.worker
2 | {
3 | import org.marz.sys.worker.MainSide;
4 | import org.puremvc.as3.interfaces.INotification;
5 | import org.puremvc.as3.patterns.command.SimpleCommand;
6 |
7 | public class WorkerReady extends SimpleCommand
8 | {
9 | public static const worker_side_ready:String = 'worker_side_ready';
10 |
11 | override public function execute(notification:INotification):void
12 | {
13 | MainSide.instance.sendMsg('hi');
14 | // MainSide.instance.sendMsg('launch_scan', '/Users/marzwu/Desktop');
15 | }
16 |
17 | }
18 | }
--------------------------------------------------------------------------------
/src/org/marz/sys/Init.as:
--------------------------------------------------------------------------------
1 | package org.marz.sys {
2 | import flash.events.Event;
3 |
4 | import org.puremvc.as3.interfaces.INotification;
5 | import org.puremvc.as3.patterns.command.SimpleCommand;
6 |
7 | public class Init extends SimpleCommand {
8 | public static const INIT:String = 'INIT';
9 |
10 | override public function execute(notification:INotification):void {
11 | Global.stage.addEventListener(Event.ENTER_FRAME, OnEnterFrameHandler);
12 | }
13 |
14 | protected function OnEnterFrameHandler(event:Event):void {
15 | sendNotification(CmdSys.ENTER_FRAME);
16 | }
17 |
18 | }
19 | }
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | SpaceSniffer
4 |
5 |
6 |
7 |
8 |
9 | com.adobe.flexbuilder.project.flexbuilder
10 |
11 |
12 |
13 |
14 | com.adobe.flexbuilder.project.apollobuilder
15 |
16 |
17 |
18 |
19 |
20 | com.adobe.flexbuilder.project.apollonature
21 | com.adobe.flexbuilder.project.actionscriptnature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/m/GridsProxy.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.m
2 | {
3 | import org.puremvc.as3.patterns.facade.Facade;
4 | import org.puremvc.as3.patterns.proxy.Proxy;
5 | import org.marz.spaceSniffer.m.vo.FileTree;
6 |
7 | public class GridsProxy extends Proxy
8 | {
9 | private static const NAME:String = 'GirdsProxy';
10 | public var fileTree:FileTree;
11 | public var fileTreeArr:Array;
12 | public var dataChanged:Boolean;
13 | public function GridsProxy()
14 | {
15 | super(NAME, null);
16 | }
17 |
18 | public static function get instance():GridsProxy
19 | {
20 | return GridsProxy(Facade.getInstance().retrieveProxy(NAME));
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/src/org/marz/sys/OnEnterFrame.as:
--------------------------------------------------------------------------------
1 | package org.marz.sys {
2 | import org.puremvc.as3.interfaces.INotification;
3 | import org.puremvc.as3.patterns.command.SimpleCommand;
4 |
5 | public class OnEnterFrame extends SimpleCommand {
6 | override public function execute(notification:INotification):void {
7 | for each (var i:Function in funcs) {
8 | i();
9 | }
10 | }
11 |
12 | private static var funcs:Object = {};
13 |
14 | public static function addFunc(key:String, func:Function):void {
15 | funcs[key] = func;
16 | }
17 |
18 | public function deleteFunc(key:String):void {
19 | delete funcs[key];
20 | }
21 | }
22 | }
--------------------------------------------------------------------------------
/src/SpaceSniffer.as:
--------------------------------------------------------------------------------
1 | package {
2 | import flash.display.Sprite;
3 |
4 | import org.puremvc.as3.patterns.facade.Facade;
5 |
6 | [SWF(width = '800', height = "600")]
7 | public class SpaceSniffer extends Sprite {
8 | public function SpaceSniffer() {
9 | // if(Worker.current.isPrimordial){
10 | initMVC();
11 | // MainSide.instance.init(loaderInfo);
12 | // MainSide.instance.start();
13 | // }else{
14 | // stage.frameRate = 2;
15 | // WorkerSide.instance.init();
16 | // WorkerSide.instance.startWorking();
17 | // }
18 | }
19 |
20 | private function initMVC():void {
21 | Facade.getInstance().registerCommand(Startup.STARTUP, Startup);
22 |
23 | Facade.getInstance().registerProxy(new StartupProxy);
24 |
25 | Facade.getInstance().sendNotification(Startup.STARTUP, stage);
26 | }
27 |
28 |
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/c/InitWorkSpaceUI.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.c {
2 | import flash.events.MouseEvent;
3 |
4 | import org.puremvc.as3.interfaces.INotification;
5 | import org.puremvc.as3.patterns.command.SimpleCommand;
6 |
7 | import shinater.swing.Menu;
8 | import shinater.swing.MenuBar;
9 | import shinater.swing.MenuItem;
10 |
11 | public class InitWorkSpaceUI extends SimpleCommand {
12 | public static const INIT_WORK_SPACE_UI:String = 'InitWorkSpaceUI';
13 |
14 | override public function execute(notification:INotification):void {
15 | var pickMenu:Menu = new Menu;
16 |
17 | var pickMenuItem:MenuItem = new MenuItem('Pick Volume');
18 | pickMenuItem.addEventListener(MouseEvent.CLICK, onChange);
19 | pickMenu.addMenuItem(pickMenuItem);
20 |
21 | var menuBar:MenuBar = new MenuBar;
22 | menuBar.addMenu(pickMenu);
23 |
24 | Global.stage.addChild(menuBar);
25 |
26 | function onChange(event:MouseEvent):void
27 | {
28 | var label:String = MenuItem(event.target).getLabel();
29 | switch(label)
30 | {
31 | case 'Pick Volume':
32 |
33 | break;
34 | default:
35 | break;
36 | }
37 | }
38 | }
39 |
40 |
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/c/ExploreFileTree.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.c {
2 | import flash.utils.getTimer;
3 |
4 | import org.marz.spaceSniffer.m.vo.FileTree;
5 | import org.marz.spaceSniffer.m.GridsProxy;
6 | import org.puremvc.as3.interfaces.INotification;
7 | import org.puremvc.as3.patterns.command.SimpleCommand;
8 |
9 | public class ExploreFileTree extends SimpleCommand {
10 | public static const EXLORE_FILE_TREE:String = 'exlore_file_tree';
11 |
12 | override public function execute(notification:INotification):void {
13 | var start:int = getTimer();
14 | var end:Number = start + 30;
15 |
16 | var arr:Array = GridsProxy.instance.fileTreeArr;
17 | if (arr.length > 0) {
18 | GridsProxy.instance.dataChanged = true;
19 | var count:int = 0;
20 | while (arr.length) {
21 | // var shiftStart:int = getTimer();
22 | var ft:FileTree = arr.shift();
23 | // trace('shift time:', getTimer() - shiftStart);
24 |
25 | // var shiftStart:int = getTimer();
26 | var directories:Array = ft.getDirectories();
27 | // trace('getDirectories time:', getTimer() - shiftStart);
28 |
29 | if (ft.file.isDirectory && ft.explored != ft.numDirectories) {
30 | // var shiftStart:int = getTimer();
31 | arr = arr.concat(directories);
32 | // trace('concat time:', getTimer() - shiftStart);
33 | }
34 |
35 | // if (count > 5) {
36 | // count = 0;
37 | if (end < getTimer()) {
38 | GridsProxy.instance.fileTreeArr = arr;
39 | trace('elapse time:', getTimer() - start, 'queue length', arr.length);
40 | break;
41 | }
42 | // }
43 | count++;
44 | }
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/org/marz/sys/worker/WorkerSide.as:
--------------------------------------------------------------------------------
1 | package org.marz.sys.worker {
2 | import flash.events.Event;
3 | import flash.system.MessageChannel;
4 | import flash.system.Worker;
5 |
6 | import org.marz.spaceSniffer.worker.LaunchScan;
7 |
8 | public class WorkerSide {
9 | private var mainToBack:MessageChannel;
10 |
11 | private var backToMain:MessageChannel;
12 |
13 | public function WorkerSide() {
14 | }
15 |
16 | private static var _instance:WorkerSide;
17 |
18 | private var processors:Object;
19 |
20 | public static function get instance():WorkerSide {
21 | if (_instance == null)
22 | _instance = new WorkerSide;
23 | return _instance;
24 | }
25 |
26 | public function init():void {
27 | var worker:Worker = Worker.current;
28 |
29 | //Listen on mainToBack for SHARPEN events
30 | mainToBack = worker.getSharedProperty("mainToBack");
31 | mainToBack.addEventListener(Event.CHANNEL_MESSAGE, onMainToBack);
32 | //Use backToMain to dispatch SHARPEN_COMPLETE
33 | backToMain = worker.getSharedProperty("backToMain");
34 | }
35 |
36 | public function startWorking():void {
37 | processors = {};
38 | processors['launch_scan'] = LaunchScan.launch;
39 | backToMain.send('worker_side_ready');
40 | }
41 |
42 | protected function onMainToBack(event:Event):void {
43 | if (mainToBack.messageAvailable) {
44 | //Get the message type.
45 | var msg:*;
46 | var args:Array = [];
47 | while (msg = mainToBack.receive())
48 | args.push(msg);
49 | trace(args);
50 |
51 | parse(args);
52 | }
53 | }
54 |
55 | private function parse(args:Array):void {
56 | var func:Function = processors[args.shift()];
57 | if (func != null)
58 | func(args);
59 | }
60 |
61 | public function sendMsg(... args):void {
62 | while (args.length)
63 | backToMain.send(args.shift());
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/v/PickVolumeMediator.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.v {
2 | import flash.events.MouseEvent;
3 | import flash.filesystem.File;
4 |
5 | import org.bellona.utils.UIUtils;
6 | import org.marz.spaceSniffer.m.vo.FileTree;
7 | import org.puremvc.as3.interfaces.INotification;
8 | import org.puremvc.as3.patterns.mediator.Mediator;
9 |
10 | import shinater.swing.Button;
11 | import shinater.swing.List;
12 | import shinater.swing.Panel;
13 | import shinater.swing.Window;
14 |
15 | public class PickVolumeMediator extends Mediator {
16 | private static const NAME:String = 'PickVolumeMediator';
17 |
18 | public static const SHOW_VOLUMES:String = 'showVolumes';
19 | public static const PICK_A_VOLUME:String = 'pickAVolume';
20 |
21 | public function PickVolumeMediator(viewComponent:Object = null) {
22 | super(NAME, viewComponent);
23 | }
24 |
25 | override public function listNotificationInterests():Array {
26 | return [SHOW_VOLUMES, PICK_A_VOLUME];
27 | }
28 |
29 | override public function handleNotification(notification:INotification):void {
30 | switch (notification.getName()) {
31 | case PICK_A_VOLUME:
32 |
33 | break;
34 | case SHOW_VOLUMES:
35 | window.setTitle('选择一个磁盘');
36 |
37 |
38 | var panel:Panel = window.getContent();
39 | panel.removeChildren();
40 |
41 | var lst:List = new List;
42 | lst.setSize(120, 150);
43 | panel.addChild(lst);
44 |
45 | var okBtn:Button = new Button('确定');
46 | okBtn.x = 160;
47 | okBtn.addEventListener(MouseEvent.CLICK, function onOkBtn(event:MouseEvent):void {
48 | var volume:String = String(lst.getSelectedItem());
49 | if (volume) {
50 | var file:File = new File(volume);
51 | sendNotification(GridsMediator.SHOW, new FileTree(file));
52 | UIUtils.removeFromParent(window);
53 | }
54 | });
55 | panel.addChild(okBtn);
56 |
57 | for each (var i:File in notification.getBody()) {
58 | lst.addItem(i.name);
59 | }
60 |
61 | window.closeButton.visible = false;
62 | window.setResizable(false);
63 | window.setModal(true);
64 | window.setVisible(true);
65 | Global.stage.addChild(window);
66 | UIUtils.centerToStage(window, window.stage);
67 | break;
68 | default:
69 | break;
70 | }
71 | }
72 |
73 |
74 | private function get window():Window {
75 | return Window(viewComponent);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/org/marz/sys/worker/MainSide.as:
--------------------------------------------------------------------------------
1 | package org.marz.sys.worker {
2 | import flash.display.LoaderInfo;
3 | import flash.events.Event;
4 | import flash.system.MessageChannel;
5 | import flash.system.Worker;
6 | import flash.system.WorkerDomain;
7 |
8 | import org.marz.spaceSniffer.worker.LaunchScan;
9 | import org.puremvc.as3.patterns.facade.Facade;
10 |
11 | public class MainSide {
12 | private var loaderInfo:LoaderInfo;
13 |
14 | private var worker:Worker;
15 |
16 | private var mainToBack:MessageChannel;
17 |
18 | private var backToMain:MessageChannel;
19 |
20 |
21 | public function MainSide() {
22 |
23 | }
24 |
25 | public function init(loaderInfo:LoaderInfo):void {
26 | this.loaderInfo = loaderInfo;
27 | }
28 |
29 | public function start():void {
30 | worker = WorkerDomain.current.createWorker(loaderInfo.bytes); //WorkerFactory.getWorkerFromClass(SharpenWorker, loaderInfo.bytes);
31 |
32 | //Create message channel TO the worker
33 | mainToBack = Worker.current.createMessageChannel(worker);
34 |
35 | //Create message channel FROM the worker, add a listener.
36 | backToMain = worker.createMessageChannel(Worker.current);
37 | backToMain.addEventListener(Event.CHANNEL_MESSAGE, onBackToMain, false, 0, true);
38 |
39 | //Now that we have our two channels, inject them into the worker as shared properties.
40 | //This way, the worker can see them on the other side.
41 | worker.setSharedProperty("backToMain", backToMain);
42 | worker.setSharedProperty("mainToBack", mainToBack);
43 |
44 | //Lastly, start the worker.
45 | worker.start();
46 | }
47 |
48 | protected function onBackToMain(event:Event):void {
49 | var msg:*;
50 | var args:Array = [];
51 | while(msg = backToMain.receive())
52 | args.push(msg);
53 | trace(args);
54 |
55 | Facade.getInstance().sendNotification(args.shift(), args);
56 | }
57 |
58 | private static var _instance:MainSide;
59 |
60 | public static function get instance():MainSide {
61 | if (_instance == null)
62 | _instance = new MainSide;
63 | return _instance;
64 | }
65 |
66 | public function sendMsg(...args):void
67 | {
68 | while(args.length)
69 | mainToBack.send(args.shift());
70 | }
71 | }
72 | }
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/v/GridsMediator.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.v {
2 | import flash.geom.Rectangle;
3 |
4 | import org.marz.spaceSniffer.c.ExploreFileTree;
5 | import org.marz.spaceSniffer.c.Refresh;
6 | import org.marz.sys.OnEnterFrame;
7 | import org.puremvc.as3.interfaces.INotification;
8 | import org.puremvc.as3.patterns.facade.Facade;
9 | import org.puremvc.as3.patterns.mediator.Mediator;
10 | import org.marz.spaceSniffer.m.vo.FileTree;
11 | import org.marz.spaceSniffer.m.GridsProxy;
12 | import org.marz.spaceSniffer.v.vo.GridRenderer;
13 |
14 | public class GridsMediator extends Mediator {
15 | private static const NAME:String = 'Grids';
16 |
17 | public static const SHOW:String = 'show';
18 |
19 | public static const UPDATE:String = 'update';
20 |
21 | private var count:int;
22 |
23 | public function GridsMediator() {
24 | super(NAME, null);
25 |
26 | facade.registerProxy(new GridsProxy);
27 | OnEnterFrame.addFunc('refresh', Refresh.doRefresh);
28 | }
29 |
30 | override public function handleNotification(notification:INotification):void {
31 | switch (notification.getName()) {
32 | case SHOW:
33 | GridsProxy.instance.fileTree = notification.getBody() as FileTree;
34 | GridsProxy.instance.fileTreeArr = GridsProxy.instance.fileTree.getDirectories();
35 | dataChanged(GridsProxy.instance.fileTree);
36 | sendNotification(ExploreFileTree.EXLORE_FILE_TREE);
37 | break;
38 | case UPDATE:
39 | if (GridsProxy.instance.fileTree) {
40 | if (GridsProxy.instance.dataChanged) {
41 | if (count == 24) {
42 | count = 0;
43 | dataChanged(GridsProxy.instance.fileTree);
44 | GridsProxy.instance.dataChanged = false;
45 | }
46 | count++;
47 | }
48 | sendNotification(ExploreFileTree.EXLORE_FILE_TREE);
49 | }
50 | default:
51 | break;
52 | }
53 | }
54 |
55 | private function dataChanged(ft:FileTree):void {
56 | Global.stage.removeChildren();
57 |
58 | var gridRenderer:GridRenderer = new GridRenderer;
59 | Global.stage.addChild(gridRenderer);
60 | var rect:Rectangle = new Rectangle(0, 0, Global.stage.stageWidth, Global.stage.stageHeight);
61 | gridRenderer.depth = 0;
62 | gridRenderer.update(ft, rect);
63 | }
64 |
65 | override public function listNotificationInterests():Array {
66 | return [SHOW, UPDATE];
67 | }
68 |
69 | public static function get instance():GridsMediator {
70 | return GridsMediator(Facade.getInstance().retrieveMediator(NAME));
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Startup.as:
--------------------------------------------------------------------------------
1 | package {
2 | import flash.display.Stage;
3 | import flash.events.Event;
4 | import flash.events.MouseEvent;
5 | import flash.filesystem.File;
6 | import flash.system.Capabilities;
7 |
8 | import org.marz.spaceSniffer.c.ExploreFileTree;
9 | import org.marz.spaceSniffer.c.InitWorkSpaceUI;
10 | import org.marz.spaceSniffer.m.vo.FileTree;
11 | import org.marz.spaceSniffer.v.GridsMediator;
12 | import org.marz.spaceSniffer.v.PickVolumeMediator;
13 | import org.marz.sys.CmdSys;
14 | import org.marz.sys.Init;
15 | import org.marz.sys.OnEnterFrame;
16 | import org.puremvc.as3.interfaces.INotification;
17 | import org.puremvc.as3.patterns.command.SimpleCommand;
18 |
19 | import shinater.swing.Menu;
20 | import shinater.swing.MenuBar;
21 | import shinater.swing.MenuItem;
22 | import shinater.swing.Window;
23 |
24 | public class Startup extends SimpleCommand {
25 | public static const STARTUP:String = 'startup';
26 |
27 | override public function execute(notification:INotification):void {
28 | var stage:Stage = notification.getBody() as Stage;
29 | Global.stage = stage;
30 | Global.stage = stage;
31 |
32 | initMVC();
33 |
34 | sendNotification(Init.INIT);
35 | sendNotification(InitWorkSpaceUI.INIT_WORK_SPACE_UI);
36 |
37 | var directories:Array = File.getRootDirectories();
38 | // sendNotification(Grids.SHOW, new FileTree(directories[0]));
39 |
40 | if (Capabilities.os.indexOf('Mac') > -1)
41 | var path:String = '/Users/marzwu/'; //Desktop Downloads
42 | else if (Capabilities.os.indexOf('Win') > -1) {
43 | // path = 'E:/klive/dirty/snatchly';
44 | // path = 'E:/klive/';
45 | path = 'E:/';
46 | sendNotification(PickVolumeMediator.SHOW_VOLUMES, directories);
47 | } else {
48 | path = '/';
49 | }
50 |
51 | // var file:File = new File(path);
52 | // sendNotification(GridsMediator.SHOW, new FileTree(file));
53 | }
54 |
55 | private function onChange(event:Event):void
56 | {
57 | trace(event);
58 | var getLabel:String = MenuItem(event.target).getLabel();
59 | }
60 |
61 | private function initMVC():void {
62 | facade.registerCommand(CmdSys.ENTER_FRAME, OnEnterFrame);
63 | // facade.registerCommand(WorkerReady.worker_side_ready, WorkerReady);
64 | facade.registerCommand(ExploreFileTree.EXLORE_FILE_TREE, ExploreFileTree);
65 | facade.registerCommand(Init.INIT, Init);
66 | facade.registerCommand(InitWorkSpaceUI.INIT_WORK_SPACE_UI, InitWorkSpaceUI);
67 |
68 | facade.registerMediator(new GridsMediator);
69 | facade.registerMediator(new PickVolumeMediator(new Window));
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/.actionScriptProperties:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/m/vo/FileTree.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.m.vo {
2 | import flash.events.FileListEvent;
3 | import flash.filesystem.File;
4 | import flash.geom.Rectangle;
5 | import flash.utils.getTimer;
6 | import org.marz.spaceSniffer.v.vo.GridRenderer;
7 |
8 | public class FileTree {
9 | public var file:File;
10 |
11 | public function FileTree(file:File) {
12 | this.file = file;
13 | if (file.isDirectory == false) {
14 | try {
15 | addSize(file.size);
16 | } catch (e:Error) {
17 | trace(e.message);
18 | }
19 | }
20 | }
21 |
22 | public var parent:FileTree;
23 |
24 | private var children:Array;
25 |
26 | private var _size:Number = 0;
27 |
28 | public var deep:int;
29 | public var numDirectories:uint;
30 | public var explored:int;
31 |
32 | private var directories:Array;
33 |
34 | public function get size():Number {
35 | return _size;
36 | }
37 |
38 | public function addSize(s:Number):Number {
39 | _size += s;
40 | sort();
41 | if (parent)
42 | parent.addSize(s);
43 | // trace('size:'+size);
44 | return size;
45 | }
46 |
47 | public function getDirectoryListing():Array {
48 | if (children)
49 | return children;
50 |
51 | if (file.isDirectory == false)
52 | return null;
53 |
54 | children = [];
55 |
56 | var sync:Boolean = true;
57 |
58 | if (sync) {
59 | // var s:int = getTimer();
60 | var list:Array = file.getDirectoryListing();
61 | // trace('getDirectoryListing time', getTimer() - s);
62 |
63 | var dSize:Number = parseList(list, children);
64 | addSize(dSize);
65 | sort();
66 | } else {
67 | file.getDirectoryListingAsync();
68 | file.addEventListener(FileListEvent.DIRECTORY_LISTING, directoryListingHandler);
69 |
70 | function directoryListingHandler(event:FileListEvent):void {
71 | var list:Array = event.files;
72 | parseList(list, children);
73 | }
74 | }
75 |
76 | return children;
77 | }
78 |
79 | private function parseList(list:Array, children:Array):Number {
80 | var r:Number = 0;
81 | for each (var i:File in list) {
82 | var ft:FileTree = new FileTree(i);
83 | ft.deep = deep + 1;
84 | ft.parent = this;
85 | children.push(ft);
86 | r += ft.size;
87 | }
88 | return r;
89 | }
90 |
91 |
92 | public function sort():void {
93 | var children:Array = getDirectoryListing();
94 | if (children) {
95 | // var s:int = getTimer();
96 | children.sortOn('size', Array.NUMERIC | Array.DESCENDING);
97 | // trace('sort time', getTimer() - s);
98 | }
99 | }
100 |
101 | public function getDirectories():Array {
102 | if (directories)
103 | return directories.concat();
104 |
105 | directories = [];
106 | for each (var i:FileTree in getDirectoryListing()) {
107 | if (i.file.isDirectory)
108 | directories.push(i);
109 | }
110 | numDirectories = directories.length;
111 |
112 | if (numDirectories == 0 && parent)
113 | parent.explored++;
114 | return directories;
115 | }
116 |
117 | public function group(renderer:GridRenderer, rect:Rectangle, children:Array, size:Number):void {
118 | var area:Number = rect.width * rect.height;
119 |
120 | var horizal:Boolean = rect.width > rect.height;
121 | var minArea:Number
122 | if (horizal)
123 | minArea = rect.height * rect.height * 0.618;
124 | else
125 | minArea = rect.width * rect.width * 0.618;
126 |
127 | var per:Number = minArea / area;
128 |
129 | var sum:Number = 0;
130 | var interval:Array = [];
131 | var w:Number = rect.width;
132 | var h:Number = rect.height;
133 |
134 | while (children.length) {
135 | var i:FileTree = children.shift();
136 | sum += i.size;
137 | interval.push(i);
138 |
139 |
140 | var dPer:Number = sum / size;
141 | if (dPer >= per) {
142 | var curr:Rectangle = rect.clone();
143 | if (horizal) {
144 | w = int(dPer * area / h);
145 | curr.width = w;
146 |
147 | rect.x += w;
148 | rect.width -= w;
149 | } else {
150 | h = int(dPer * area / w);
151 | curr.height = h;
152 |
153 | rect.y += h;
154 | rect.height -= h;
155 | }
156 |
157 | if (dPer < 1)
158 | group(renderer, curr, interval, sum);
159 | else {
160 | // renderer.graphics.lineStyle(1);
161 |
162 | renderGroup(renderer, interval, sum, curr.x, curr.y, curr.width, curr.height);
163 |
164 | // if (interval.length == 1) {
165 | //// renderer.graphics.drawRect(curr.x, curr.y, curr.width, curr.height);
166 | // render(renderer, interval[0], curr.x, curr.y, curr.width, curr.height);
167 | // } else {
168 | // var dHorizal:Boolean = curr.width > curr.height;
169 | // var dd:int;
170 | // if (dHorizal) {
171 | // dd = curr.width * interval[0].size / sum;
172 | //// renderer.graphics.drawRect(curr.x, curr.y, dd, curr.height);
173 | //// renderer.graphics.drawRect(curr.x + dd, curr.y, curr.width - dd, curr.height);
174 | // render(renderer, interval[0], curr.x, curr.y, dd, curr.height);
175 | // render(renderer, interval[1], curr.x + dd, curr.y, curr.width - dd, curr.height);
176 | // } else {
177 | // dd = curr.height * interval[0].size / sum;
178 | //// renderer.graphics.drawRect(curr.x, curr.y, curr.width, dd);
179 | //// renderer.graphics.drawRect(curr.x, curr.y + dd, curr.width, curr.height - dd);
180 | // render(renderer, interval[0], curr.x, curr.y, curr.width, dd);
181 | // render(renderer, interval[1], curr.x, curr.y + dd, curr.width, curr.height - dd);
182 | // }
183 | // }
184 | }
185 |
186 | group(renderer, rect.clone(), children, size - sum);
187 | break;
188 | }
189 | }
190 | }
191 |
192 | private function renderGroup(renderer:GridRenderer, interval:Array, sum:Number, x:Number, y:Number, width:Number, height:Number):void {
193 | var dHorizal:Boolean = width > height;
194 | var dd:int;
195 | var cursor:Number = 0;
196 | for each (var i:FileTree in interval) {
197 | var scale:Number = cursor / sum;
198 | if (dHorizal) {
199 | dd = width * scale;
200 | render(renderer, i, x + dd, y, width * i.size / sum, height);
201 | } else {
202 | dd = height * scale;
203 | render(renderer, i, x, y + dd, width, height * i.size / sum);
204 | }
205 | cursor += i.size;
206 | }
207 | }
208 |
209 | private function render(renderer:GridRenderer, f:FileTree, x:Number, y:Number, width:Number, height:Number):void {
210 | var r:GridRenderer = new GridRenderer;
211 | r.x = x;
212 | r.y = y;
213 | r.depth = renderer.depth + 1;
214 | r.update(f, new Rectangle(0, 0, width, height));
215 | renderer.addChild(r);
216 | }
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/src/org/marz/spaceSniffer/v/vo/GridRenderer.as:
--------------------------------------------------------------------------------
1 | package org.marz.spaceSniffer.v.vo {
2 | import flash.display.Sprite;
3 | import flash.events.ContextMenuEvent;
4 | import flash.events.MouseEvent;
5 | import flash.geom.Rectangle;
6 | import flash.ui.ContextMenu;
7 | import flash.ui.ContextMenuItem;
8 |
9 | import org.puremvc.as3.patterns.facade.Facade;
10 |
11 | import shinater.swing.Label;
12 | import org.marz.spaceSniffer.m.vo.FileTree;
13 | import org.marz.spaceSniffer.v.GridsMediator;
14 |
15 | public class GridRenderer extends Sprite {
16 | private static const min_size:int = 5;
17 |
18 | private static const LABEL_HEIGHT:Number = 20;
19 |
20 | private static const UNIT_ARR:Array = new Array("Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB");
21 |
22 | private var label:Label;
23 |
24 | public function GridRenderer() {
25 | super();
26 | label = new Label('path 0');
27 |
28 | this.doubleClickEnabled = true;
29 |
30 | // addEventListener(MouseEvent.CLICK, onClick);
31 | addEventListener(MouseEvent.DOUBLE_CLICK, onClick);
32 | // addEventListener(MouseEvent.RIGHT_CLICK, onClick);
33 |
34 | var menu:ContextMenu = new ContextMenu;
35 | this.contextMenu = menu;
36 |
37 | var item:ContextMenuItem;
38 | item = new ContextMenuItem('parent');
39 | item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onMenuItemSelected);
40 | menu.items.push(item);
41 | item = new ContextMenuItem('open');
42 | item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onMenuItemSelected);
43 | menu.items.push(item);
44 | item = new ContextMenuItem('delete');
45 | item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, onMenuItemSelected);
46 | menu.items.push(item);
47 | }
48 |
49 | protected function onMenuItemSelected(event:ContextMenuEvent):void {
50 | switch (event.target.caption) {
51 | case 'parent':
52 | if (fileTree.parent) {
53 | Facade.getInstance().sendNotification(GridsMediator.SHOW, fileTree.parent);
54 | }
55 | break;
56 | case 'open':
57 | try{
58 | fileTree.file.openWithDefaultApplication();
59 | }catch(e:Error){
60 | trace(e);
61 | }
62 | break;
63 | case 'delete':
64 | if (fileTree.file.isDirectory)
65 | fileTree.file.deleteDirectory(true);
66 | else
67 | fileTree.file.deleteFile();
68 | break;
69 | }
70 | }
71 |
72 | protected function onClick(event:MouseEvent):void {
73 | switch (event.type) {
74 | case MouseEvent.CLICK:
75 | break;
76 | case MouseEvent.DOUBLE_CLICK:
77 | Facade.getInstance().sendNotification(GridsMediator.SHOW, fileTree);
78 | break;
79 | case MouseEvent.RIGHT_CLICK:
80 | break;
81 | }
82 | event.stopImmediatePropagation();
83 | }
84 |
85 | public function update(fileTree:FileTree, rect:Rectangle):void {
86 | this.fileTree = fileTree;
87 |
88 | if (depth > 2)
89 | return;
90 |
91 | // if (rect.width < min_size || rect.height < min_size)
92 | // return;
93 |
94 | graphics.clear();
95 | graphics.lineStyle(1);
96 | if (fileTree.file.isDirectory)
97 | graphics.beginFill(0x008888, .8);
98 | else
99 | graphics.beginFill(0xffffff, .8);
100 |
101 | graphics.drawRect(0, 0, rect.width, rect.height);
102 | graphics.endFill();
103 |
104 | var name:String = fileTree.file.nativePath;
105 | name = name.substr(name.lastIndexOf('/') + 1);
106 | name = name.substr(name.lastIndexOf('\\') + 1);
107 | label.setAutoSize('left');
108 |
109 | var size:Number = fileTree.size;
110 | var _index:int;
111 | var sizeStr:String = (size / Math.pow(1024, (_index = int(Math.log(size) / Math.log(1024))))).toPrecision(3) + UNIT_ARR[_index];
112 | if (fileTree.file.isDirectory)
113 | label.setText(name + ': ' + sizeStr);
114 | else
115 | label.setText(name + '\n' + sizeStr);
116 |
117 | if (rect.width < label.width)
118 | label.setText(sizeStr + '');
119 |
120 | if (rect.width >= label.width && rect.height >= label.height) {
121 | addChild(label);
122 |
123 | if (false == fileTree.file.isDirectory) {
124 | label.x = (width - label.width) >> 1;
125 | label.y = (height - label.height) >> 1;
126 | }
127 | }
128 |
129 | horizal = rect.width > rect.height;
130 |
131 | if (fileTree.file.isDirectory) {
132 | var list:Array = fileTree.getDirectoryListing();
133 |
134 | var clientW:Number = rect.width - min_size * 2;
135 | var clientH:Number = rect.height - LABEL_HEIGHT - min_size;
136 |
137 | var area:int = clientW * clientH;
138 |
139 | var acturalW:Number = clientW;
140 | var acturalH:Number = clientH;
141 | var cursorX:int = min_size;
142 | var cursorY:int = LABEL_HEIGHT;
143 |
144 | if (clientW < 1 || clientH < 1)
145 | return;
146 |
147 | fileTree.group(this, new Rectangle(cursorX, cursorY, acturalW, acturalH), fileTree.getDirectoryListing().concat(), size);
148 | return;
149 |
150 | for each (var i:FileTree in list) {
151 | var renderer:GridRenderer = new GridRenderer;
152 | renderer.depth = depth + 1;
153 |
154 | horizal = acturalW > acturalH;
155 |
156 | if (horizal) {
157 | renderer.x = cursorX;
158 | renderer.y = cursorY;
159 |
160 | var h:Number = acturalH;
161 | var w:int = area * (i.size / size) / h;
162 | renderer.update(i, new Rectangle(0, 0, Math.max(1, w), Math.max(1, h)));
163 |
164 | cursorX += w;
165 | acturalW -= w;
166 | } else {
167 | renderer.x = cursorX;
168 | renderer.y = cursorY;
169 |
170 | w = acturalW;
171 | h = area * (i.size / size) / w;
172 |
173 | renderer.update(i, new Rectangle(0, 0, Math.max(1, w), Math.max(1, h)));
174 |
175 | cursorY += h;
176 | acturalH -= h;
177 | }
178 | addChild(renderer);
179 | }
180 | }
181 | }
182 |
183 | private var _depth:int;
184 |
185 | public function get depth():int {
186 | return _depth;
187 | }
188 |
189 | public function set depth(value:int):void {
190 | if (_depth == value)
191 | return;
192 | _depth = value;
193 | }
194 |
195 | public var horizal:Boolean;
196 |
197 | public var fileTree:FileTree;
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/src/SpaceSniffer-app.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
15 |
16 |
18 | SpaceSniffer
19 |
20 |
21 | SpaceSniffer
22 |
23 |
25 | SpaceSnifferAnywhere
26 |
27 |
30 | 1.0.0
31 |
32 |
33 |
34 |
35 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | [This value will be overwritten by Flash Builder in the output app.xml]
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | false
113 | false
114 | true
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
136 |
153 |
154 |
157 |
158 |
159 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
208 |
209 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
--------------------------------------------------------------------------------