/******************************************************************************* * Copyright (c) 2014, 2016 itemis AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Matthias Wienand (itemis AG) - initial API and implementation * *******************************************************************************/ package org.eclipse.gef.mvc.fx.parts; import java.util.List; import java.util.Set; import org.eclipse.gef.common.adapt.AdapterKey; import org.eclipse.gef.fx.nodes.GeometryNode; import org.eclipse.gef.fx.utils.NodeUtils; import org.eclipse.gef.geometry.planar.ICurve; import org.eclipse.gef.geometry.planar.IGeometry; import org.eclipse.gef.mvc.fx.models.SelectionModel; import org.eclipse.gef.mvc.fx.viewer.IViewer; import com.google.common.reflect.TypeToken; import com.google.inject.Provider; import javafx.scene.Node; import javafx.scene.paint.Color; import javafx.scene.shape.StrokeType; /** * The {@link SelectionFeedbackPart} is an {@link AbstractFeedbackPart} that is * parameterized by <code>GeometryNode<IGeometry></code>. * * @author mwienand * */ public class SelectionFeedbackPart extends AbstractFeedbackPart<GeometryNode<IGeometry>> { /** * The stroke width for selection feedback. */ protected static final double DEFAULT_STROKE_WIDTH = 1.5d; private Provider<? extends IGeometry> feedbackGeometryProvider; /** * Default constructor. */ public SelectionFeedbackPart() { } @Override protected GeometryNode<IGeometry> doCreateVisual() { GeometryNode<IGeometry> feedbackVisual = new GeometryNode<>(); feedbackVisual.setFill(Color.TRANSPARENT); feedbackVisual.setMouseTransparent(true); feedbackVisual.setManaged(false); feedbackVisual.setStrokeWidth(DEFAULT_STROKE_WIDTH); return feedbackVisual; } @Override public void doRefreshVisual(GeometryNode<IGeometry> visual) { Set<IVisualPart<? extends Node>> anchorages = getAnchoragesUnmodifiable() .keySet(); if (anchorages.isEmpty()) { return; } IVisualPart<? extends Node> anchorage = anchorages.iterator().next(); IRootPart<? extends Node> root = anchorage.getRoot(); if (root == null) { return; } IViewer viewer = anchorage.getRoot().getViewer(); if (viewer == null) { return; } IGeometry feedbackGeometry = getFeedbackGeometry(); if (feedbackGeometry == null) { return; } // FIXME: Investigate why the StrokeType needs to be set before setting // the geometry in order to prevent a vertical offset. // update stroke type if (feedbackGeometry instanceof ICurve) { // stroke centered visual.setStrokeType(StrokeType.CENTERED); } else { // stroke outside visual.setStrokeType(StrokeType.OUTSIDE); // TODO: adjust stroke width to get hair lines } // update geometry visual.setGeometry(feedbackGeometry); // update color List<IContentPart<? extends Node>> selected = viewer .getAdapter(SelectionModel.class).getSelectionUnmodifiable(); if (selected != null && selected.size() > 0 && selected.get(0) == anchorage) { // primary selection visual.setStroke(getPrimarySelectionColor()); } else { // secondary selection visual.setStroke(getSecondarySelectionColor()); } } /** * Returns the {@link IGeometry} that is provided by this part's * {@link #setGeometryProvider(Provider) feedback geometry provider}. * * @return The {@link IGeometry} that is provided by this part's * {@link #setGeometryProvider(Provider) feedback geometry provider} * . */ protected IGeometry getFeedbackGeometry() { return NodeUtils.sceneToLocal(getVisual().getParent(), feedbackGeometryProvider.get()); } /** * Returns the primary selection {@link Color}. * * @return The primary selection {@link Color}. */ protected Color getPrimarySelectionColor() { @SuppressWarnings("serial") Provider<Color> connectedColorProvider = getViewer() .getAdapter(AdapterKey.get(new TypeToken<Provider<Color>>() { }, DefaultSelectionFeedbackPartFactory.PRIMARY_SELECTION_FEEDBACK_COLOR_PROVIDER)); return connectedColorProvider == null ? DefaultSelectionFeedbackPartFactory.DEFAULT_PRIMARY_SELECTION_FEEDBACK_COLOR : connectedColorProvider.get(); } /** * Returns the primary selection {@link Color}. * * @return The primary selection {@link Color}. */ protected Color getSecondarySelectionColor() { @SuppressWarnings("serial") Provider<Color> connectedColorProvider = getViewer() .getAdapter(AdapterKey.get(new TypeToken<Provider<Color>>() { }, DefaultSelectionFeedbackPartFactory.SECONDARY_SELECTION_FEEDBACK_COLOR_PROVIDER)); return connectedColorProvider == null ? DefaultSelectionFeedbackPartFactory.DEFAULT_SECONDARY_SELECTION_FEEDBACK_COLOR : connectedColorProvider.get(); } /** * Sets the feedback geometry provider ( * <code>Provider<IGeometry></code>) of this part to the given value. * * @param geometryProvider * The new feedback geometry provider for this part. */ public void setGeometryProvider( Provider<? extends IGeometry> geometryProvider) { feedbackGeometryProvider = geometryProvider; } }