S-JIS[2013-12-29] 変更履歴

Eclipse GEF フィードバック

Eclipseプラグイン開発GEFの図形操作のフィードバックについて。

 

概要

エディター上の図形をマウスでドラッグしている最中に対象図形の背景色を変えたりする処理は「フィードバック」で行う。

フィードバックの際に呼ばれるメソッドはEditPartにあるが、そこから(EditPartに登録している)各Policyクラスのメソッドが呼ばれるので、フィードバック処理はPolicyクラスに実装する。

※ドラッグ中にマウスカーソルの形を変えることは出来ないらしい。
参考: Eclipse Community ForumsのCursor while drag and drop


図形をドラッグしている最中に、マウスの指し先にある図形の背景色を変更する例。

対象図形に登録されているGraphicalNodeEditPolicy

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.geometry.Point;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.GraphicalNodeEditPolicy;
import org.eclipse.gef.requests.ChangeBoundsRequest;
public class ElementGraphicalNodeEditPolicy extends GraphicalNodeEditPolicy {
	private RectangleFigure feedbackFigure;
	private NodeElementEditPart nowTarget;
〜
	@Override
	public void eraseSourceFeedback(Request request) {
		feedback(null);
		super.eraseSourceFeedback(request);
	}
	@Override
	public void showSourceFeedback(Request request) {
		if (REQ_MOVE.equals(request.getType())) {
			ChangeBoundsRequest crequest = (ChangeBoundsRequest) request;
			Point mouse = crequest.getLocation();
			NodeElementEditPart target = getFeedbackTarget(mouse);
			feedback(target);
		}
		super.showSourceFeedback(request);
	}

	private NodeElementEditPart getFeedbackTarget(Point mouse) {
		// マウスの指している場所の図形を取得
		NodeElementEditPart sourcePart = (NodeElementEditPart) getHost();
		GraphicalEditPart diagramPart = sourcePart.getParent();
		EditPart targetEditPart = diagramPart.getViewer().findObjectAt(mouse);
		if (targetEditPart == sourcePart) {
			// ドラッグ元の図形と同じ場合
			return null;
		}
		if (targetEditPart instanceof NodeElementEditPart) {
			// フィードバックしたい図形の場合
			NodeElementEditPart target = (NodeElementEditPart) targetEditPart;
			return target;
		}
		return null;
	}

	private void feedback(NodeElementEditPart target) {
		// フィードバック対象図形が無い場合 または 変更になった場合
		if (target == null || nowTarget != target) {
			if (feedbackFigure != null) {
				// フィードバック用のFigureを削除
				getFeedbackLayer().remove(feedbackFigure);
				feedbackFigure = null;
				nowTarget = null;
			}
		}

		if (target != null && feedbackFigure == null) {
			// フィードバック用のFigureを作成
			feedbackFigure = new RectangleFigure();
			feedbackFigure.setBackgroundColor(ColorConstants.blue); //背景色
			feedbackFigure.setFillXOR(true); //描画先の色と排他的論理和をとって色を反転させる
			feedbackFigure.setBounds(target.getFigure().getBounds()); //図形の位置とサイズ
			getFeedbackLayer().add(feedbackFigure);
			nowTarget = target;
		}
	}
}

図形をドラッグして移動させるとshowSourceFeedback()が呼ばれる。
色々なイベント(Request)で呼ばれるので、自分が扱いたいリクエストである場合だけ処理する。
getFeedbackLayer()でフィードバック用のレイヤーを取得し、フィードバック用Figureを追加する。

フィードバック関連の処理が終わるときにeraseSourceFeedback()が呼ばれる。
ここで、フィードバック用レイヤーから自分が追加したFigureを削除する。


対象となった図形の情報をリクエストに保存しておけば、後続処理でリクエストを使うときにその情報を取得することが出来る。

	@SuppressWarnings("unchecked")
	@Override
	public void showSourceFeedback(Request request) {
		if (REQ_MOVE.equals(request.getType())) {
			ChangeBoundsRequest crequest = (ChangeBoundsRequest) request;
			Point mouse = crequest.getLocation();
			NodeElementEditPart target = getFeedbackTarget(mouse);
			feedback(target);

			request.getExtendedData().put("targetEditPart", target);
		}
		super.showSourceFeedback(request);
	}

GEFへ戻る / Eclipseプラグインへ戻る / Eclipseへ戻る / 技術メモへ戻る
メールの送信先:ひしだま