コネクションの途中のベンドポイントをドラッグしたときの動作

org.eclipse.gef.tools.SelectionTool#mouseDragから始まって
org.eclipse.gmf.runtime.gef.ui.internal.tools.ConnectionBendpointTrackerEx#mouseDragへ。
handleDragInProgress内のupdateSourceRequestでBendpointRequestが作成される。

続いてshowSourceFeedbackでフィードバックの更新を行う。
EditPartのshowSourceFeedbackへ。作成したBendpointRequestを渡している。

SimpleDragTracker
protected void showSourceFeedback() {
List editParts = getOperationSet();
for (int i = 0; i < editParts.size(); i++) {
	EditPart editPart = (EditPart) editParts.get(i);
	editPart.showSourceFeedback(getSourceRequest());
}
setFlag(FLAG_SOURCE_FEEDBACK, true);
}

リクエストはインストールされているポリシーのshowSourceFeedbackへ委譲される。

public void showSourceFeedback(Request request) {
if (!isActive())
	return;
EditPolicyIterator i = getEditPolicyIterator();
while (i.hasNext())
	i.next()
		.showSourceFeedback(request);
}

反応するポリシー
org.eclipse.gmf.runtime.diagram.ui.internal.editpolicies.ConnectionLineSegEditPolicy extends ConnectionBendpointEditPolicy
org.eclipse.gmf.runtime.diagram.ui.editpolicies.ConnectionBendpointEditPolicy extends org.eclipse.gmf.runtime.gef.ui.internal.editpolicies.ConnectionBendpointEditPolicy
(org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicyとは違う)

このクラスの
org.eclipse.gmf.runtime.gef.ui.internal.editpolicies.ConnectionBendpointEditPolicyで定義されているメソッドが動く。

public void showSourceFeedback(Request request) {
	if (getLineSegMode() != LineMode.OBLIQUE) {
		if (REQ_CREATE_BENDPOINT.equals(request.getType())) {
			showMoveLineSegFeedback((BendpointRequest) request);
		} else if (REQ_MOVE_BENDPOINT.equals(request.getType())) {
			showMoveOrthogonalBenspointFeedback((BendpointRequest) request);
		}
		
	} else {
		if (REQ_MOVE_BENDPOINT.equals(request.getType()))
			showMoveBendpointFeedback((BendpointRequest) request);
		else if (REQ_CREATE_BENDPOINT.equals(request.getType()))
			showCreateBendpointFeedback((BendpointRequest) request);
	}
	super.showSourceFeedback(request);
}


例えば今showMoveOrthogonalBenspointFeedbackが動いて
constraint にはAbsoluteBendpointが5つ入っていた。
リクエストから、今何番目を動かしているかを取得して、前後のポイントを取得している。
	Point previous = ((Bendpoint)constraint.get(index - 1)).getLocation();
	Point moving = ((Bendpoint)constraint.get(index)).getLocation();
	Point next = ((Bendpoint)constraint.get(index + 1)).getLocation();
3つのポイントから、2つのセグメントを作成している。
	LineSeg originalFirst = new LineSeg(previous.getCopy(), moving.getCopy());
	LineSeg originalSecond = new LineSeg(moving.getCopy(), next.getCopy());

結局、ここで制約(constraint)をアップデートして、コネクションのコネクションルーターConnectionRouterにセットしている。
これでフィードバックは更新されるよう。


private void showMoveOrthogonalBenspointFeedback(BendpointRequest request) {
	if (getFeedbackState().originalConstraint == null) {
		saveOriginalConstraint();
	}
	
	Point ptLoc = new Point(request.getLocation());
	List constraint = (List)
		getConnection().getRoutingConstraint();
	
	getConnection().translateToRelative(ptLoc);
	
	int index =
	getFeedbackState().isOutsideSource ? request.getIndex() + 1 : request.getIndex();
	
	Point previous = ((Bendpoint)constraint.get(index - 1)).getLocation();
	Point moving = ((Bendpoint)constraint.get(index)).getLocation();
	Point next = ((Bendpoint)constraint.get(index + 1)).getLocation();
	
	LineSeg originalFirst = new LineSeg(previous.getCopy(), moving.getCopy());
	LineSeg originalSecond = new LineSeg(moving.getCopy(), next.getCopy());
	
	Dimension diff = ptLoc.getDifference(moving);
	
	if (originalFirst.isHorizontal()) {
		previous.y += diff.height;
		next.x += diff.width;
	} else {
		previous.x += diff.width;
		next.y += diff.height;
	}
	
	LineSeg movedFirst = new LineSeg(previous, ptLoc.getCopy());
	LineSeg movedSecond = new LineSeg(ptLoc.getCopy(), next);
	
	index = adjustOutsideBoundsLineFeedback(movedFirst, index - 1, constraint, originalFirst);
	constraint.set(index, new AbsoluteBendpoint(movedFirst.getOrigin()));
	constraint.set(index + 1, new AbsoluteBendpoint(movedFirst.getTerminus()));
	
	index = adjustOutsideBoundsLineFeedback(movedSecond, index + 1, constraint, originalSecond);
	constraint.set(index + 1, new AbsoluteBendpoint(movedSecond.getTerminus()));
	
	getConnection().setRoutingConstraint(constraint);	}


adjustOutsideBoundsLineFeedbackでは何をしているのか


private int adjustOutsideBoundsLineFeedback(LineSeg newLine, int index, List constraint, LineSeg moveLine) {
	if (getLineSegMode().equals(LineMode.ORTHOGONAL_CONSTRAINED)) {
		// merely enforce the fact that we can't adjust the line outside the bounds of the source and target.
		if ((index == 0 && lineOutsideSource(newLine)) ||
			((index + 1 == constraint.size() - 1)&& lineOutsideTarget(newLine))) {
			newLine.setOrigin(moveLine.getOrigin());
			newLine.setTerminus(moveLine.getTerminus());
		}

		return index;
	}
	
	boolean bRemoveSource = false;
	boolean bRemoveTarget = false;
	boolean bSetNewSource = false;
	boolean bSetNewTarget = false;

	// Check source to see if we need to add a bendpoint
	if (index == 0 && lineOutsideSource(newLine)) {
		if (!getFeedbackState().isOutsideSource) {
			getFeedbackState().isOutsideSource = true;
			bSetNewSource = true;
		}
	} else if (index == 1 && getFeedbackState().isOutsideSource && !lineOutsideSource(newLine)) {
		getFeedbackState().isOutsideSource = false;
		bRemoveSource = true;
	}
	
	// Check target to see if we need to add a bendpoint
	int checkTargetIndex = index + 1 + (getFeedbackState().isOutsideTarget ? 1 : 0);
	if ((checkTargetIndex == constraint.size() - 1)
		&& lineOutsideTarget(newLine)) {
		if (!getFeedbackState().isOutsideTarget) {
			getFeedbackState().isOutsideTarget = true;
			bSetNewTarget = true;
		}
	} else if (checkTargetIndex == constraint.size() - 2 && getFeedbackState().isOutsideTarget
			&& !lineOutsideTarget(newLine)) {
		getFeedbackState().isOutsideTarget = false;
		bRemoveTarget = true;
	}
	if (bRemoveSource) {
		removeOutsideSourceFeedback(constraint);
		index--;
	}
	
	if (bRemoveTarget) {
		removeOutsideTargetFeedback(constraint);
	}

	if (bSetNewSource) {
		showOutsideSourceFeedback(newLine, moveLine, constraint);
		index++;
	}

	if (bSetNewTarget) {
		showOutsideTargetFeedback(newLine, moveLine, constraint);
	}
	return index;
}







続くgetCommandでorg.eclipse.gmf.runtime.diagram.ui.editparts.ConnectionEditPartのgetCommandが呼び出される。



ノードとノードを接続して、接続線のENDPOINTを動かしたときの動作
コネクション等
アンカー
(0.55,0.8)


ConnectionNodeEditPartのhandleNotificationEventが呼ばれる

anchorChangeが呼ばれる
 refreshSourceAnchor
 refreshTargetAnchor
が呼ばれる

この中で、NodeFigureがSlidableAnchorを作成
最終更新:2008年12月15日 01:28
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。