Flex Air 实现桌面尺子(Ruler)工具

最近在使用Flex Air写桌面应用,因为有个测量的需求,就想着自己写个尺子来用。经过琢磨,写了个简陋版,希望大家指正。 先上图:


以下是代码:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx"
                       showStatusBar="false" minWidth="80" minHeight="80"
                       alpha="0.7" doubleClickEnabled="true"
                       initialize="appInitializeHandler(event)"
                       creationComplete="appCreationCompleteHandler(event)"
                       applicationComplete="init(event)"
                       mouseMove="appMouseMoveHandler(event)">
   <fx:Script>
      <![CDATA[
         import mx.controls.Menu;
         import mx.events.FlexEvent;
         import mx.events.MenuEvent;
         
         import spark.layouts.HorizontalLayout;
         
         private var properties:Object = new Object();
         private var appMenu:Menu;
         private var mode:String;

         protected function init(event:FlexEvent):void {
            this.stage.addEventListener(KeyboardEvent.KEY_DOWN, appKeyDownHandler);
            this.stage.addEventListener(MouseEvent.RIGHT_CLICK, appRightClickHandler);
            this.stage.addEventListener(MouseEvent.DOUBLE_CLICK, appDoubleClickHandler);
         }
         
         override protected function createChildren():void {
            super.createChildren();
            
            var menuData:Array = [{label: "退出", id: "AppExt"}];
            appMenu = Menu.createMenu(this, menuData);
            appMenu.addEventListener(MenuEvent.ITEM_CLICK, menuItemClickHandler);
         }
         
         protected function menuItemClickHandler(event:MenuEvent):void {
            if(event.item["id"] == "AppExt") {
               nativeWindow.close();
            }
         }
         
         override protected function mouseDownHandler(event:MouseEvent):void {
            this.nativeWindow.startMove();
         }
         
         protected function appMouseMoveHandler(event:MouseEvent):void {
            if(!event.altKey) {
               return;
            }
            
            if(mode == "h") {
               lineGrp.y = 0;
               lineGrp.x = mouseX;
               showText((lineGrp.x + 1) + "");
            }
            else if(mode == "v") {
               lineGrp.x = 0;
               lineGrp.y = mouseY;
               showText((lineGrp.y + 1) + "");
            }
         }
         
         protected function appKeyDownHandler(event:KeyboardEvent):void {
            if(!(event.keyCode == Keyboard.LEFT && 
               event.keyCode == Keyboard.RIGHT && 
               event.keyCode == Keyboard.DOWN &&
               event.keyCode == Keyboard.UP)) 
            {
               return;
            }
            
            if(event.keyCode == Keyboard.LEFT) {
               if(lineGrp.x == 0) {
                  return;
               }

               lineGrp.x -= 1;
            }
            
            if(event.keyCode == Keyboard.RIGHT) {
               lineGrp.x += 1;
            }
            
            showText((lineGrp.x + 1) + "");
         }
         
         private function showText(text:String):void {
            display.text = text;
         }
         
         protected function appDoubleClickHandler(event:MouseEvent):void {
            mode = mode == "h" ? "v" : "h";
            appChanged();
         }
         
         override public function get minWidth():Number {
            return 80;
         }
         
         protected function appRightClickHandler(event:MouseEvent):void {
            appMenu.show(event.stageX, event.stageY);
         }
         
         protected function appInitializeHandler(event:FlexEvent):void {
            var init:File = File.applicationDirectory.resolvePath("Ruler.ini");
            var reader:FileStream = new FileStream();
            reader.open(init, FileMode.READ);
            var initValues:Array = 
               reader.readUTFBytes(reader.bytesAvailable).split("\r\n");

            for each(var value:String in initValues) {
               var property:Array = value.split("=");
               properties[property[0]] = property[1];
            }

            reader.close();
         }
         
         protected function appCreationCompleteHandler(event:FlexEvent):void {
            mode = getProperty("initMode");
            appChanged();
         }
         
         private function appChanged():void {
            if(mode == "h") {
               lineGrp.x = 20;
               lineGrp.y = 0;
               lineGrp.width = 3;
               lineGrp.percentHeight = 100;
               line.width = 0;
               line.percentHeight = 100;
               ticks.percentWidth = 100;
               ticks.height = 20;
               leftResizer.enabled = rightResizer.enabled = true;
               upResizer.enabled = downResizer.enabled = false;
               labelGrp.layout = new VerticalLayout();
               this.width = Number(getProperty("initHWidth"));
               this.height = Number(getProperty("initHHeight"));
            }
            else if(mode == "v") {
               lineGrp.x = 0;
               lineGrp.y = 20;
               lineGrp.percentWidth = 100;
               lineGrp.height = 3;
               line.percentWidth = 100;
               line.height = 0;
               ticks.width = 20;
               ticks.percentHeight = 100;
               leftResizer.enabled = rightResizer.enabled = false;
               upResizer.enabled = downResizer.enabled = true;
               labelGrp.layout = new HorizontalLayout();
               this.width = Number(getProperty("initVWidth"));
               this.height = Number(getProperty("initVHeight"));
            }

            drawTicks();
            layoutResizer();
         }
         
         override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
            if(mode == "v") {
               unscaledWidth = 80;
            }
            else if(mode == "h") {
               unscaledHeight = 80;
            }
            
            super.updateDisplayList(unscaledWidth, unscaledHeight);
         }
         
         private function getProperty(key:String):String {
            return properties[key];
         }
         
         private function setProperty(key:String, value:String):void {
            properties[key] = value;
         }
         
         protected function resizerClickHandler(event:MouseEvent):void {
            var resizer:String = event.currentTarget.id;
            
            if(resizer == "leftResizer") {
               this.width -= 100;
            }
            else if(resizer == "rightResizer") {
               this.width += 100;
            }
            else if(resizer == "upResizer") {
               this.height -= 40;
            }
            else if(resizer == "downResizer") {
               this.height += 40;
            }
            
            drawTicks();
            layoutResizer();
         }
         
         private function drawTicks():void {
            ticks.removeAllElements();
            var g:Graphics = ticks.graphics;
            g.clear();
            g.lineStyle(0, 0x000000);

            if(mode == "h") {
               for(var i:int = 0; i < this.width; i++) {
                  if(i % 50 == 0) {
                     g.moveTo(i, 0);
                     g.lineTo(i, 10);
                     
                     var hLabel:Label = new Label();
                     hLabel.text = i + "";
                     hLabel.setStyle("fontSize", 10);
                     hLabel.x = i - (3 * (i + "").length);
                     hLabel.y = 12;
                     ticks.addElement(hLabel);
                  }
                  else if(i % 5 == 0) {
                     g.moveTo(i, 0);
                     g.lineTo(i, 5);
                  }
               }
            }
            else if(mode == "v") {
               for(var j:int = 0; j < this.height; j++) {
                  if(j % 50 == 0) {
                     g.moveTo(0, j);
                     g.lineTo(10, j);
                     
                     var vLabel:Label = new Label();
                     vLabel.text = j + "";
                     vLabel.setStyle("fontSize", 10);
                     vLabel.x = 12;//i - (3 * (i + "").length);
                     vLabel.y = j - 3;
                     ticks.addElement(vLabel);
                  }
                  else if(j % 5 == 0) {
                     g.moveTo(0, j);
                     g.lineTo(5, j);
                  }
               }
            }
         }
         
         private function layoutResizer():void {
            if(mode == "v") {
               resizerGrp.x = 80 - 48;
            }
            else {
               resizerGrp.x = this.width - 5 - 48;
            }
            
            resizerGrp.y = this.height - 5 - 48;
         }
         
         protected function resizerDoubleClickHandler(event:MouseEvent):void {
            event.stopImmediatePropagation();
         }
         
      ]]>
   </fx:Script>

   <s:BorderContainer id="ruler" width="100%" height="100%" borderVisible="false">
      <s:backgroundFill>
         <s:SolidColor color="0x00FF00" alpha="0.4">
         </s:SolidColor>
      </s:backgroundFill>
      <s:Group id="labelGrp" width="100%" height="100%">
         <s:layout>
            <s:VerticalLayout />
         </s:layout>
         <s:Group id="ticks">
         </s:Group>
         <s:Label id="display" width="100%" height="100%" textAlign="center" verticalAlign="middle" />
      </s:Group>
      <s:Group id="resizerGrp" width="48" height="48">
         <s:Image id="upResizer" source="assets/up.png" x="11" y="0" click="resizerClickHandler(event)" doubleClickEnabled="false" doubleClick="resizerDoubleClickHandler(event)" />
         <s:Image id="downResizer" source="assets/down.png" x="11" y="22" click="resizerClickHandler(event)" doubleClickEnabled="false" doubleClick="resizerDoubleClickHandler(event)" />
         <s:Image id="leftResizer" source="assets/left.png" x="0" y="11" click="resizerClickHandler(event)" doubleClickEnabled="false" doubleClick="resizerDoubleClickHandler(event)" />
         <s:Image id="rightResizer" source="assets/right.png" x="22" y="11" click="resizerClickHandler(event)" doubleClickEnabled="false" doubleClick="resizerDoubleClickHandler(event)" />
      </s:Group>
      <s:HGroup id="lineGrp" x="20" width="3" height="100%" horizontalAlign="center" verticalAlign="middle" >
         <s:Line id="line" height="100%">
            <s:stroke>
               <s:SolidColorStroke weight="1" />
            </s:stroke>
         </s:Line>
      </s:HGroup>
   </s:BorderContainer>
</s:WindowedApplication>

使用方法:按住alt键的同时移动鼠标,可以移动指示线; 在尺子上双击,可以切换横竖模式;点击箭头可以增加减少尺子长度。

可执行文件下载地址: http://download.csdn.net/detail/ptheus/7343231

转载请著名出处,图迹科技www.togeek.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值