orchestra
Rev 6221 | Blame | Compare with Previous | Last modification | View Log | RSS feed
/*
* Bull SAS / OW2 Orchestra
* Copyright (C) 2011 Bull S.A.S, and individual contributors as indicated
* by the @authors tag.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*/
package org.ow2.orchestra.designer.bpmn.views {
import flash.display.DisplayObject;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.binding.utils.BindingUtils;
import mx.binding.utils.ChangeWatcher;
import mx.containers.Canvas;
import mx.containers.HBox;
import mx.containers.VBox;
import mx.controls.Image;
import mx.controls.Label;
import mx.controls.Spacer;
import mx.events.FlexEvent;
import org.ow2.orchestra.designer.bpmn.model.AbstractElement;
import org.ow2.orchestra.designer.bpmn.model.TaskModel;
import org.ow2.orchestra.designer.bpmn.model.TaskType;
import org.ow2.orchestra.designer.bpmn.views.utils.ArrowStyle;
import org.ow2.orchestra.designer.bpmn.views.utils.ArrowUtil;
import org.ow2.orchestra.designer.bpmn.views.utils.GraphicUtils;
public class TaskView extends AbstractElementView implements IFlowNodeView {
[Bindable]
private var _taskModel:TaskModel;
private var _processView:ProcessView;
/**
* The source for "event" image data binding.
*/
[Bindable]
[Embed(source="/../assets/task.svg")]
public var taskBackgroundImage:Class;
/**
* The source for "event" image data binding.
*/
[Bindable]
[Embed(source="/../assets/serviceTask.svg")]
public var serviceTaskImage:Class;
private var imageTaskBackground:Image = new Image();
private var imageTask:Image = new Image();
private var messageFlowCanvas:Canvas = new Canvas();
private var messageFlowLabel:Label = new Label();
function TaskView(taskModel:TaskModel, processView:ProcessView) {
_processView = processView;
_taskModel = taskModel;
this.setStyle("horizontalAlign", "center");
imageTaskBackground.percentWidth = 100;
imageTaskBackground.minWidth = 60;
imageTaskBackground.percentHeight = 100;
imageTaskBackground.maintainAspectRatio = false;
imageTaskBackground.automationName = "TaskImage" + _taskModel.id;
imageTaskBackground.source = taskBackgroundImage;
watchers.addItem(BindingUtils.bindProperty(this, "x", _taskModel, "x"));
watchers.addItem(BindingUtils.bindProperty(this, "y", _taskModel, "y"));
var label:Label = new Label();
watchers.addItem(BindingUtils.bindProperty(label, "text", _taskModel, "name"));
watchers.addItem(ChangeWatcher.watch(_taskModel, "taskType", updateImage));
watchers.addItem(ChangeWatcher.watch(_taskModel, "operation", redraw));
watchers.addItem(ChangeWatcher.watch(this, "x", redraw));
watchers.addItem(ChangeWatcher.watch(this, "y", redraw));
var canvas:Canvas = new Canvas();
canvas.addChild(imageTaskBackground);
imageTask.x = 3;
imageTask.y = 3;
imageTask.height = 16;
imageTask.width = 16;
canvas.addChild(imageTask);
var hbox:HBox = new HBox();
hbox.percentWidth = 100;
hbox.percentHeight = 100;
var s1:Spacer = new Spacer();
s1.percentWidth = 100;
var s2:Spacer = new Spacer();
s2.percentWidth = 100;
var vbox:VBox = new VBox();
vbox.percentHeight = 100;
vbox.percentWidth = 100;
var s3:Spacer = new Spacer();
s3.height = 10;
var s4:Spacer = new Spacer();
s4.height = 5;
vbox.addChild(s3);
vbox.addChild(label);
vbox.addChild(s4);
hbox.addChild(s1);
hbox.addChild(vbox);
hbox.addChild(s2);
canvas.addChild(hbox);
this.addChild(canvas);
messageFlowCanvas.clipContent = false;
messageFlowCanvas.autoLayout = false;
messageFlowCanvas.width = 0;
messageFlowCanvas.height = 0;
this.addChild(messageFlowCanvas);
messageFlowCanvas.addChild(messageFlowLabel);
this.addEventListener(FlexEvent.CREATION_COMPLETE, updateImage);
}
override public function get model():AbstractElement {
return _taskModel;
}
override public function copy():AbstractElementView {
return new TaskView(_taskModel, _processView);
}
override public function get borderImage():DisplayObject {
return imageTaskBackground;
}
override public function get subtypeImage():DisplayObject {
return imageTask;
}
protected function updateImage(event:Event = null):void {
if (_taskModel.taskType == TaskType.SERVICE) {
imageTask.source = serviceTaskImage;
}
this.redraw();
}
protected function redraw(event:Event = null):void {
var clearMsgFlow:Boolean = false;
if (_taskModel.taskType == TaskType.SERVICE
&& _taskModel.operation != null
&& _taskModel.operation.interfaceModel != null
&& _taskModel.operation.interfaceModel.poolModel != null) {
var targetView:AbstractElementView = this._processView.getElementViewByModel(_taskModel.operation.interfaceModel.poolModel);
if (targetView != null) {
// get source and target border image
var sourceImage:DisplayObject = this.borderImage;
// get image centers in y, and this view center in x
var sourceCenterPoint:Point = this.localToGlobal(new Point(sourceImage.x + (sourceImage.width / 2), sourceImage.y + (sourceImage.height / 2)));
var targetCenterPoint:Point = this._processView.localToGlobal(new Point(0, targetView.y + (targetView.height / 2)));
targetCenterPoint.x = sourceCenterPoint.x;
// update source and target points
var sourcePoint:Point = GraphicUtils.findIntersection(sourceImage, sourceCenterPoint, targetCenterPoint, _processView);
var targetPoint:Point = GraphicUtils.findIntersection(targetView.borderImage, targetCenterPoint, sourceCenterPoint, _processView);
// draw arrow
var style:ArrowStyle = new ArrowStyle();
style.headWidth = 11;
style.headLength = 17;
style.color = 0x000000;
style.headFill = false;
style.thickness = 0;
style.isDashed = true;
style.isMessage = true;
var localTarget:Point = messageFlowCanvas.globalToLocal(targetPoint);
messageFlowLabel.text = _taskModel.operation.name;
messageFlowLabel.width = messageFlowLabel.measureText(messageFlowLabel.text).width + 10;
messageFlowLabel.y = localTarget.y + 10;
if (_taskModel.operation.outMessageType == null) {
messageFlowLabel.x = localTarget.x + 10;
ArrowUtil.drawArrow(messageFlowCanvas.graphics, messageFlowCanvas.globalToLocal(sourcePoint), messageFlowCanvas.globalToLocal(targetPoint), style);
} else {
messageFlowLabel.x = localTarget.x + 20;
sourcePoint.x -= 10;
targetPoint.x -= 10;
ArrowUtil.drawArrow(messageFlowCanvas.graphics, messageFlowCanvas.globalToLocal(sourcePoint), messageFlowCanvas.globalToLocal(targetPoint), style);
sourcePoint.x += 20;
targetPoint.x += 20;
ArrowUtil.drawArrow(messageFlowCanvas.graphics, messageFlowCanvas.globalToLocal(targetPoint), messageFlowCanvas.globalToLocal(sourcePoint), style, false);
}
} else {
clearMsgFlow = true;
}
} else {
clearMsgFlow = true;
}
if (clearMsgFlow) {
messageFlowCanvas.graphics.clear();
messageFlowLabel.text = "";
}
}
////////////////////////////////////////////////////////////////////////////////////////
// Override selection function: clicking on a message flow should not select the task //
////////////////////////////////////////////////////////////////////////////////////////
override public function includeInto(selection:Rectangle, targetCoordinateSpace:DisplayObject):Boolean {
var bounds:Rectangle = this.borderImage.getRect(targetCoordinateSpace);
return selection.containsRect(bounds);
}
override public function containsRectangle(selection:Rectangle, targetCoordinateSpace:DisplayObject):Boolean {
var objectRect:Rectangle = this.borderImage.getRect(targetCoordinateSpace);
return objectRect.containsRect(selection);
}
public function getCollisionRectangle(targetCoordinateSpace:DisplayObject):Rectangle {
return this.borderImage.getRect(targetCoordinateSpace);
}
}
}