模型
主画布组件:com/components/graph/GraphContainer.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init(event)"
width="100%" height="100%">
<fx:Script>
<![CDATA[
import com.components.model.ShapeModel;
import com.roguedevelopment.objecthandles.Flex4ChildManager;
import com.roguedevelopment.objecthandles.Flex4HandleFactory;
import com.roguedevelopment.objecthandles.HandleClickedEvent;
import com.roguedevelopment.objecthandles.ObjectChangedEvent;
import com.roguedevelopment.objecthandles.ObjectHandles;
import com.roguedevelopment.objecthandles.SelectionEvent;
import com.components.shape.BaseShape;
import com.components.shape.IShape;
import com.components.shape.ShapeLoad;
import com.components.shape.SimpleRect; import mx.controls.Alert;
import mx.controls.Button;
import mx.core.UIComponent;
import mx.events.DragEvent;
import mx.events.FlexEvent;
import mx.managers.DragManager;
[Bindable]
public var objecthandles:ObjectHandles = null; override protected function initializationComplete() : void
{
objecthandles = new ObjectHandles( mainGroup , null, new Flex4HandleFactory() ,
new Flex4ChildManager() );
super.initializationComplete();
} private function init(event:FlexEvent):void
{
this.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void{
if(event.target is IShape) {
if(objecthandles.selectionManager.currentlySelected.length > 1){
objecthandles.selectionManager.clearSelection();
}
}else{
objecthandles.selectionManager.clearSelection();
}
event.stopPropagation();
});
} protected function mainGroup_dragDropHandler(event:DragEvent):void
{
// TODO Auto-generated method stub } public function addShapeUI(shape:ShapeModel):void
{
var ishape:IShape = ShapeLoad.getShape(shape.shapeType);
ishape.graph = this;
ishape.model = shape; shape.ishape = ishape;
if (shape.owner) {
var container:IShape = shape.owner.ishape if (container) {
// Alert.show(container.model.label);//alert Test
var oh:ObjectHandles = new ObjectHandles(container as Sprite, objecthandles.selectionManager, new Flex4HandleFactory(), new Flex4ChildManager());
oh.registerComponent(shape, ishape, []); container.addShape(ishape);
} else {
Alert.show("null");
}
} else { mainGroup.addElement(ishape); objecthandles.registerComponent(shape, ishape); //shapeModel Bindable #1069
} if (shape.children && shape.children.length > 0) {
for (var i:int=0;i<shape.children.length;i++) {
var child:ShapeModel = shape.children[i];
addShapeUI(child);
}
} ishape.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
// ishape.objectHandles.selectionManager.setSelected(shape);
event.stopPropagation(); //important
}); ishape.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void{
// ishape.objectHandles.selectionManager.setSelected(shape);
event.stopPropagation(); //important
}); } public function removeShapeUI(shape:ShapeModel):void
{
if (shape.owner) {
var container:IShape = shape.owner.ishape
container.removeChildByModel(shape);
} else {
for (var i:int=0;i<mainGroup.numElements;i++) {
var ishape:IShape = mainGroup.getElementAt(i) as IShape; if (ishape.model == shape) {
objecthandles.unregisterComponent(ishape);
mainGroup.removeElement(ishape);
}
}
}
} ]]>
</fx:Script>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations> <s:Scroller width="100%" height="100%" >
<s:Group width="100%" height="100%" id="mainGroup"> </s:Group>
</s:Scroller>
</s:Group>
GraphModel.as: com/components/model/
package com.components.model
{ public class GraphModel
{
public function GraphModel()
{ }
}
}
ShapeModel.as: 图形模型类,用于设置图形宽、高、坐标等参数
package com.components.model
{
import com.roguedevelopment.objecthandles.IMoveable;
import com.roguedevelopment.objecthandles.IResizeable;
import com.components.shape.IShape; import flash.events.EventDispatcher;
import flash.events.MouseEvent; import mx.messaging.AbstractConsumer; public class ShapeModel extends EventDispatcher implements IResizeable, IMoveable
{
[Bindable]
private var _width:Number = 0;
[Bindable]
private var _height:Number = 0;
[Bindable]
private var _x:Number = 0;
[Bindable]
private var _y:Number = 0;
[Bindable]
private var _rotation:Number = 0;
[Bindable]
private var _label:String = '';
[Bindable]
private var _isLocked:Boolean = false;
[Bindable]
private var _color:uint = 0xffffff;
[Bindable]
private var _image:String;
[Bindable]
private var _ishape:IShape;
[Bindable]
private var _owner:ShapeModel = null;
[Bindable]
private var _children:Array;
[Bindable]
private var _shapeType:int = 0; public function ShapeModel()
{ } public function set width(value:Number):void
{
this._width = value;
} [Bindable]
public function get width():Number
{
return this._width;
} public function set height(value:Number):void
{
this._height = value;
} [Bindable]
public function get height():Number
{
return this._height;
} public function set x(value:Number):void
{
this._x = value;
} [Bindable]
public function get x():Number
{
return this._x;
} public function set y(value:Number):void
{
this._y = value;
} [Bindable]
public function get y():Number
{
return this._y;
} public function set rotation(value:Number):void
{
this._rotation = value;
} [Bindable]
public function get rotation():Number
{
return this._rotation;
} public function set label(value:String):void
{
this._label = value;
} [Bindable]
public function get label():String
{
return this._label;
} public function set isLocked(value:Boolean):void
{
this._isLocked = value;
} [Bindable]
public function get isLocked():Boolean
{
return this._isLocked;
} //-------------------- [Bindable]
public function get ishape():IShape
{
return this._ishape;
} public function set ishape(value:IShape):void
{
this._ishape = value;
} public function set children(childs:Array):void
{
this._children = childs; if (childs && childs.length > 0) {
var c:* = childs[0]; //检测是不是ShapeModel类型
if (c is ShapeModel){
for each(var itm:ShapeModel in childs) {
itm.owner = this;
}
}
}
} [Bindable]
public function get children():Array
{
return this._children;
} public function set owner(value:ShapeModel):void
{
this._owner = value;
} [Bindable]
public function get owner():ShapeModel
{
return this._owner;
} // public function set color(value:uint):void
{
this._color = value;
} [Bindable]
public function get color():uint
{
return this._color;
} public function set image(value:String):void
{
this._image = value;
} [Bindable]
public function get image():String
{
return this._image;
} public function set shapeType(value:int):void
{
this._shapeType = value;
} [Bindable]
public function get shapeType():int {
return this._shapeType;
} public function setSelected(flag:Boolean):void {
if (this._ishape) {
if (flag) {
this._ishape.objectHandles.selectionManager.setSelected(this);
} else {
this._ishape.objectHandles.selectionManager.removeFromSelected(this);
}
}
}
}
}
图形基组件: com/components/shape/BaseShape.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
implements="com.components.shape.IShape"
creationComplete="init(event)"
width="{_model.width}"
height="{_model.height}"
x="{_model.x}"
y="{_model.y}"
rotation="{_model.rotation}" >
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
<s:SolidColor id="backColor" color="0xdcdcdc" alpha="1" />
<s:SolidColorStroke id="borderStroke" color="0x000000" weight="1" alpha="1" />
</fx:Declarations> <fx:Script>
<![CDATA[
import com.components.graph.GraphContainer;
import com.components.model.ShapeModel;
import com.events.ShapeEvent;
import com.roguedevelopment.objecthandles.Flex4ChildManager;
import com.roguedevelopment.objecthandles.Flex4HandleFactory;
import com.roguedevelopment.objecthandles.ObjectHandles;
import com.utils.ShapeUtils; import mx.controls.Alert;
import mx.events.FlexEvent; [Bindable]private var _objectHandles:ObjectHandles ;
[Bindable]private var _graph:GraphContainer;
[Bindable]private var _model:ShapeModel;
[Bindable]private var _showLabel:Boolean;
[Bindable]private var _selected:Boolean; private var _state:int = 0;
private var _rx:Number = 0;
private var _ry:Number = 0; private function init(event:FlexEvent):void
{
var that:IShape = this;
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandle);
this.addEventListener(MouseEvent.MOUSE_OUT, mousOutHandle);
this.addEventListener(MouseEvent.MOUSE_OVER, mouseOverHandle);
//this.addEventListener(MouseEvent.MOUSE_WHEEL, mouWheelHandle); //从没出现
this.addEventListener(MouseEvent.ROLL_OUT, mouRolOutHandle);
this.addEventListener(MouseEvent.ROLL_OVER, mouRolOverHandle);
//this.addEventListener(MouseEvent.RELEASE_OUTSIDE, mouseOutsideHandle);//从没出现
} private function mouseDownHandle(event:MouseEvent):void { _rx = this.mouseX;
_ry = this.mouseY;
this.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandle);
this.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandle); } //
private function mousOutHandle(event:MouseEvent):void
{
var cm:ShapeModel = this.model;
if (cm) {
if (cm.x < 0) {
cm.x = 0;
} if (cm.y < 0) {
cm.y = 0
}
}
this.model.label = "MouseOut"; } private function mouseOutsideHandle(event:MouseEvent):void
{
this.model.label = "Outside";
} private function mouseOverHandle(event:MouseEvent):void
{
this.model.label = "MouseOver";
ResizeContainer(this);
} private function mouWheelHandle(event:MouseEvent):void
{
this.model.label = "MouseWheel";
} private function mouRolOutHandle(event:MouseEvent):void
{
var cm:ShapeModel = this.model;
if (cm) {
if (cm.x < 0) {
cm.x = 0;
} if (cm.y < 0) {
cm.y = 0
}
} this.model.label = "RollOut";
ResizeContainer(this); } private function mouRolOverHandle(event:MouseEvent):void
{
this.model.label = "MouseRollOver";
} private function mouseMoveHandle(event:MouseEvent):void {
if (_state != 6) {
_state = 6; }
this.model.label = "MouseMove"; ResizeContainer(this, event);
} private function mouseUpHandle(event:MouseEvent):void {
if (_state != 7) {
_state = 7;
} this.model.label = "UP";
this.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandle);
this.removeEventListener(MouseEvent.MOUSE_DOWN, mouseMoveHandle);
// this.removeEventListener(MouseEvent.MOUSE_OUT, mousOutHandle);
// this.removeEventListener(MouseEvent.ROLL_OUT, mouRolOutHandle);
// this.removeEventListener(MouseEvent.MOUSE_OVER, mouseOverHandle);
var cm:ShapeModel = this.model; if (!cm || !cm.owner)
return; /*
var xy:Object = ShapeUtils.getRealShapePosition(cm); var _pw:Number = cm.owner.width;
var _ph:Number = cm.owner.height;
var _px:Number = cm.owner.x;
var _py:Number = cm.owner.y; if (cm.x<0) {
cm.owner.x = Number(xy.x);
cm.owner.width = _pw + (_px - Number(xy.x));
cm.x = 0;
} if (cm.y <0) {
cm.owner.y = Number(xy.y);
cm.owner.height = _ph + (_py - Number(xy.y));
cm.y = 0;
}*/
} private function ResizeContainer(shapeui:IShape, event:MouseEvent = null):void
{
var cm:ShapeModel = shapeui.model;
if (cm && cm.owner) {
var _x:Number = cm.x;
var _y:Number = cm.y;
var _w:Number = cm.width;
var _h:Number = cm.height; var _pw:Number = cm.owner.width;
var _ph:Number = cm.owner.height;
var _px:Number = cm.owner.x;
var _py:Number = cm.owner.y; var xy:Object = ShapeUtils.getRealShapePosition(cm);
this.model.label = "Rs"; /*
//Resize Right, Down
if ((_x+_w) > _pw) {
cm.owner.width = _x + _w;
} if ((_y + _h) > _ph) {
cm.owner.height = _y + _h;
} //Resize Left , UP
if (_x < 0) {
cm.owner.x = _px + (_x);
cm.owner.width = _pw + (-_x);
} if (_y < 0) {
cm.owner.y = _py + (_y);
cm.owner.height = _ph + (-_y);
} */ } else {
this.model.label = "Where";
}
} public function get objectHandles():ObjectHandles
{
if (!this._objectHandles) {
this._objectHandles = new ObjectHandles(this, null, new Flex4HandleFactory(), new Flex4ChildManager());
} return this._objectHandles;
} public function set graph(value:GraphContainer):void
{
this._graph = value;
if (this._graph) {
this._objectHandles = this._graph.objecthandles;
}
} public function get graph():GraphContainer
{
return this._graph;
} public function set model(value:ShapeModel):void
{
this._model = value;
} [Bindable]
public function get model():ShapeModel
{
return this._model;
} public function set selected(value:Boolean):void
{
this._selected = value;
} public function get selected():Boolean
{
return this._selected;
} public function addShape(shapeui:IShape):void
{
ResizeContainer(shapeui);
} public function removeChildByModel(shape:ShapeModel):void { } public function set showLabel(value:Boolean):void
{
this._showLabel = value;
} public function get showLabel():Boolean
{
return this._showLabel;
} ]]>
</fx:Script> </s:Group>
Shape图形接口: IShape.as
package com.components.shape
{
import com.components.graph.GraphContainer;
import com.components.model.ShapeModel;
import com.roguedevelopment.objecthandles.ObjectHandles; import mx.core.IUIComponent;
import mx.core.IVisualElement;
import mx.core.IVisualElementContainer; public interface IShape extends IUIComponent, IVisualElement, IVisualElementContainer
{
function set graph(value:GraphContainer):void;
function get graph():GraphContainer;
function set model(value:ShapeModel):void;
function get model():ShapeModel;
function addShape(shapeui:IShape):void;
function removeChildByModel(shape:ShapeModel):void;
function set showLabel(value:Boolean):void;
function get showLabel():Boolean;
function get objectHandles():ObjectHandles;
//
function set selected(value:Boolean):void;
function get selected():Boolean;
}
}
图形ShapeModel与具体图形如SimpleRect.mxml[IShape]转换: ShapeLoad.as
package com.components.shape
{
public class ShapeLoad
{
public function ShapeLoad()
{
} public static function getShape(stype:int):IShape
{
var shape:BaseShape;
switch (stype) {
case 0:
shape = new SimpleRect();
break;
case 1:
shape = new SimpleEllipse();
break;
default:
break;
} return shape;
}
}
}
一个矩形图组件: com/components/shape/SimpleRect.mxml
<?xml version="1.0" encoding="utf-8"?>
<shape:BaseShape
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:shape="com.components.shape.*"
width="{model.width}"
height="{model.height}"
x="{model.x}"
y="{model.y}"
rotation="{model.rotation}" >
<fx:Script>
<![CDATA[
import com.components.model.ShapeModel; import mx.controls.Alert;
import mx.core.IVisualElement;
import mx.core.UIComponent;
import mx.events.FlexEvent; override public function addShape(shapeui:IShape):void
{
container.addElement(shapeui);
super.addShape(shapeui);
} override public function removeChildByModel(shape:ShapeModel):void
{
for (var i:int = 0; i<container.numElements;i++) {
var ishape:IShape = container.getElementAt(i) as IShape;
if (ishape && ishape.model == shape) {
objectHandles.unregisterComponent(ishape);
container.removeElement(ishape);
}
}
} override public function set showLabel(value:Boolean):void
{
super.showLabel = value;
} [Bindable]
override public function get showLabel():Boolean
{
return true;
} protected function scrollDown_clickHandler(event:MouseEvent):void
{
// TODO Auto-generated method stub
var itm:Object = event.target as DisplayObject; var tyName:String = itm.name;
if (tyName && tyName.indexOf('Button') >= 0) {
event.stopPropagation();
objectHandles.selectionManager.clearSelection();
} } protected function scrollUp_clickHandler(event:MouseEvent):void
{ } ]]>
</fx:Script> <s:Rect width="100%" height="100%" stroke="{borderStroke}" fill="{backColor}" />
<s:Scroller width="100%" height="100%" mouseDown="scrollDown_clickHandler(event)" mouseUp="scrollUp_clickHandler(event)">
<s:Group id="container" width="100%" height="100%" horizontalCenter="0" verticalCenter="0" />
</s:Scroller>
<s:Label text="{model.label}" horizontalCenter="0" verticalCenter="0" color="#000000" />
</shape:BaseShape>
使用方法Application: Flex4objectHandles.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
width="100%" height="100%"
xmlns:graph="com.components.graph.*"
creationComplete="init(event)" >
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.components.model.ShapeModel; import mx.controls.Alert;
import mx.events.FlexEvent; private function init(event:FlexEvent):void
{
var shape:ShapeModel = new ShapeModel();
shape.shapeType = 1;
shape.width = 400;
shape.height = 300;
shape.x = 15;
shape.y = 30;
shape.label = "Test";
shape.rotation = 0; var childs:Array = [];
var child:ShapeModel = new ShapeModel();
child.shapeType = 0;
child.width = 100;
child.height = 100;
child.x = 60;
child.y = 90;
child.label = "child1";
child.rotation = 0;
childs.push(child); var _child:ShapeModel = new ShapeModel();
_child.shapeType = 0;
_child.width = 50;
_child.height = 50;
_child.x = 60;
_child.y = 90;
_child.label = "child1";
_child.rotation = 0;
child.children = [_child]; child = new ShapeModel();
child.shapeType = 1;
child.width = 50;
child.height = 50;
child.x = 70;
child.y = 10;
child.label = "child2";
child.rotation = 0;
childs.push(child); shape.children = childs; graph.addShapeUI(shape);
}
]]>
</fx:Script>
<s:SpriteVisualElement width="100%" height="100%" id="drawingLayer" />
<s:Group width="100%" height="100%">
<graph:GraphContainer id="graph" width="100%" height="100%"></graph:GraphContainer>
</s:Group>
</s:Application>
资源源码下载