/*******************************************************************************
* Copyright (c) 2017 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.behaviors;
import org.eclipse.gef.mvc.fx.models.HoverModel;
import org.eclipse.gef.mvc.fx.parts.IContentPart;
import org.eclipse.gef.mvc.fx.parts.IFeedbackPartFactory;
import org.eclipse.gef.mvc.fx.parts.IHandlePartFactory;
import org.eclipse.gef.mvc.fx.viewer.IViewer;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;
/**
* The {@link HoverIntentBehavior} complements the {@link HoverBehavior} w.r.t.
* feedback and handle generation in response to {@link HoverModel} changes.
* While {@link HoverBehavior} is responsible for generating feedback and
* handles for the {@link HoverModel#hoverProperty()}, the
* {@link HoverIntentBehavior} is responsible for generating feedback and
* handles for the {@link HoverModel#hoverIntentProperty()}.
*
* @author wienand
*
*/
// FIXME: Support multiple different feedback and handle contexts within
// AbstractBehavior so that multiple factories can be used for feedback and
// handle generation from a single Behavior.
public class HoverIntentBehavior extends AbstractBehavior {
/**
* The adapter role for the {@link IFeedbackPartFactory} that is used to
* generate hover feedback parts.
*/
public static final String HOVER_INTENT_FEEDBACK_PART_FACTORY = "HOVER_INTENT_FEEDBACK_PART_FACTORY";
/**
* The adapter role for the {@link IHandlePartFactory} that is used to
* generate hover handle parts.
*/
public static final String HOVER_INTENT_HANDLE_PART_FACTORY = "HOVER_INTENT_HANDLE_PART_FACTORY";
private ChangeListener<IContentPart<? extends Node>> hoverIntentObserver = new ChangeListener<IContentPart<? extends Node>>() {
@Override
public void changed(
ObservableValue<? extends IContentPart<? extends Node>> observable,
IContentPart<? extends Node> oldValue,
IContentPart<? extends Node> newValue) {
onHoverIntentChange(oldValue, newValue);
}
};
@Override
protected void doActivate() {
// register
HoverModel hoverModel = getHoverModel();
hoverModel.hoverIntentProperty().addListener(hoverIntentObserver);
// create feedback and handles for a part that is already the hover
// intent
IContentPart<? extends Node> hoverIntent = hoverModel.getHoverIntent();
if (hoverIntent != null) {
onHoverIntentChange(null, hoverIntent);
}
}
@Override
protected void doDeactivate() {
// remove any pending feedback and handles
HoverModel hoverModel = getHoverModel();
IContentPart<? extends Node> hoverIntent = hoverModel.getHoverIntent();
if (hoverIntent != null) {
onHoverIntentChange(hoverIntent, null);
}
// unregister
hoverModel.hoverIntentProperty().removeListener(hoverIntentObserver);
// remove any pending feedback and handles
clearFeedback();
clearHandles();
}
@Override
protected IFeedbackPartFactory getFeedbackPartFactory(IViewer viewer) {
return getFeedbackPartFactory(viewer,
HOVER_INTENT_FEEDBACK_PART_FACTORY);
}
@Override
protected IHandlePartFactory getHandlePartFactory(IViewer viewer) {
return getHandlePartFactory(viewer, HOVER_INTENT_HANDLE_PART_FACTORY);
}
/**
* Returns the {@link HoverModel} in the context of the {@link #getHost()
* host}.
*
* @return The {@link HoverModel} in the context of the {@link #getHost()
* host}.
*/
protected HoverModel getHoverModel() {
IViewer viewer = getHost().getRoot().getViewer();
HoverModel hoverModel = viewer.getAdapter(HoverModel.class);
return hoverModel;
}
/**
* Callback method that is invoked when the
* {@link HoverModel#hoverIntentProperty()} changes. Triggers
* generation/removal of feedback and handles.
*
* @param oldHoverIntent
* The previous hover intent {@link IContentPart}.
* @param newHoverIntent
* The new hover intent {@link IContentPart}.
*/
protected void onHoverIntentChange(
IContentPart<? extends Node> oldHoverIntent,
IContentPart<? extends Node> newHoverIntent) {
// check if changed
if (oldHoverIntent == newHoverIntent) {
return;
}
// remove feedback/handles from the old hover intent part
if (oldHoverIntent != null) {
removeHandles(oldHoverIntent);
removeFeedback(oldHoverIntent);
}
// add feedback/handles to the new hover intent part
if (newHoverIntent != null) {
addFeedback(newHoverIntent);
addHandles(newHoverIntent);
}
}
}