/*******************************************************************************
* 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 & implementation
*
*******************************************************************************/
package org.eclipse.gef.zest.fx.parts;
import java.util.Set;
import org.eclipse.gef.mvc.fx.parts.AbstractFeedbackPart;
import org.eclipse.gef.mvc.fx.parts.IVisualPart;
import org.eclipse.gef.zest.fx.models.HidingModel;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
/**
* The {@link HiddenNeighborsFeedbackPart} is an {@link AbstractFeedbackPart}
* that displays the number of hidden neighbors (see
* {@link HidingModel#getHiddenNeighbors(org.eclipse.gef.graph.Node)}) of its
* first anchorage.
*
* @author mwienand
*
*/
// TODO: only applicable for NodePart (anchorage)
public class HiddenNeighborsFeedbackPart extends AbstractFeedbackPart<Group> {
private Circle circle;
private Text text;
@Override
protected void doAttachToAnchorageVisual(IVisualPart<? extends Node> anchorage, String role) {
super.doAttachToAnchorageVisual(anchorage, role);
getVisual().visibleProperty().bind(anchorage.getVisual().visibleProperty());
}
// TODO: extract visual to its own type
@Override
protected Group doCreateVisual() {
Group visual = new Group();
visual.setAutoSizeChildren(false);
circle = new Circle(10);
// TODO: move to CSS
circle.setFill(Color.RED);
circle.setStroke(Color.BLACK);
text = new Text("0");
visual.getChildren().addAll(circle, text);
return visual;
}
@Override
protected void doDetachFromAnchorageVisual(IVisualPart<? extends Node> anchorage, String role) {
super.doDetachFromAnchorageVisual(anchorage, role);
getVisual().visibleProperty().unbind();
}
@Override
protected void doRefreshVisual(Group visual) {
Set<IVisualPart<? extends Node>> keySet = getAnchoragesUnmodifiable().keySet();
if (keySet.isEmpty()) {
return;
}
IVisualPart<? extends Node> anchorage = keySet.iterator().next();
if (((NodePart) anchorage).getContent() == null) {
return;
}
// update position
Bounds anchorageLayoutBoundsInLocal = getVisual()
.sceneToLocal(anchorage.getVisual().localToScene(anchorage.getVisual().getLayoutBounds()));
double x = anchorageLayoutBoundsInLocal.getMaxX();
double y = anchorageLayoutBoundsInLocal.getMaxY();
circle.setCenterX(x);
circle.setCenterY(y);
// update text
HidingModel hidingModel = getViewer().getAdapter(HidingModel.class);
int count = hidingModel.getHiddenNeighbors(((NodePart) anchorage).getContent()).size();
text.setText(Integer.toString(count));
Bounds textLayoutBounds = text.getLayoutBounds();
// update circle size
double size = textLayoutBounds.getWidth();
if (textLayoutBounds.getHeight() > size) {
size = textLayoutBounds.getHeight();
}
circle.setRadius(size / 2);
// update text position
text.relocate(x - textLayoutBounds.getWidth() / 2, y - textLayoutBounds.getHeight() / 2);
}
}