/*******************************************************************************
* Copyright (c) 2014, 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.models;
import org.eclipse.gef.common.dispose.IDisposable;
import org.eclipse.gef.mvc.fx.parts.IContentPart;
import org.eclipse.gef.mvc.fx.parts.IVisualPart;
import org.eclipse.gef.mvc.fx.viewer.IViewer;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.MapChangeListener;
import javafx.scene.Node;
/**
* The {@link HoverModel} is used to store the current viewer's mouse hover
* target, i.e. the {@link IVisualPart} that is currently under the mouse
* cursor.
*
* @author mwienand
*
*/
public class HoverModel
extends org.eclipse.gef.common.adapt.IAdaptable.Bound.Impl<IViewer>
implements IDisposable {
/**
* This is the name of the property that stores the currently hovered
* {@link IVisualPart}.
*/
final public static String HOVER_PROPERTY = "hover";
/**
* This property stores the intended hovered
*/
final public static String HOVER_INTENT_PROPERTY = "hoverIntent";
private ObjectProperty<IVisualPart<? extends Node>> hoverProperty = new SimpleObjectProperty<>(
this, HOVER_PROPERTY);
private ObjectProperty<IContentPart<? extends Node>> hoverIntentProperty = new SimpleObjectProperty<>(
this, HOVER_INTENT_PROPERTY);
private MapChangeListener<Node, IVisualPart<? extends Node>> visualPartMapListener = new MapChangeListener<Node, IVisualPart<? extends Node>>() {
@Override
public void onChanged(
javafx.collections.MapChangeListener.Change<? extends Node, ? extends IVisualPart<? extends Node>> change) {
// keep model in sync with part hierarchy
if (change.wasRemoved()) {
IVisualPart<? extends Node> valueRemoved = change
.getValueRemoved();
if (hoverProperty.get() == valueRemoved) {
clearHover();
}
if (hoverIntentProperty.get() == valueRemoved) {
clearHoverIntent();
}
}
}
};
/**
* Sets the hovered part to <code>null</code>.
*/
public void clearHover() {
setHover(null);
}
/**
* Sets the intentionally hovered part to <code>null</code>.
*/
public void clearHoverIntent() {
setHoverIntent(null);
}
/**
* @since 1.1
*/
@Override
public void dispose() {
// setAdaptable() already clears hover and hoverIntent
}
/**
* Returns the currently hovered {@link IVisualPart} or <code>null</code> if
* no visual part is hovered.
*
* @return the currently hovered {@link IVisualPart} or <code>null</code>
*/
public IVisualPart<? extends Node> getHover() {
return hoverProperty.get();
}
/**
* Returns the current hover intent {@link IContentPart} or
* <code>null</code> if no content part is intentionally hovered.
*
* @return The current hover intent {@link IContentPart} or
* <code>null</code>
*/
public IContentPart<? extends Node> getHoverIntent() {
return hoverIntentProperty.get();
}
/**
* Returns an object property representing the hover intent part.
*
* @return A property named {@link #HOVER_INTENT_PROPERTY}.
*/
public ObjectProperty<IContentPart<? extends Node>> hoverIntentProperty() {
return hoverIntentProperty;
}
/**
* Returns an object property representing the current hover part.
*
* @return A property named {@link #HOVER_PROPERTY}.
*/
public ObjectProperty<IVisualPart<? extends Node>> hoverProperty() {
return hoverProperty;
}
@Override
public void setAdaptable(IViewer adaptable) {
if (getAdaptable() != null) {
// unregister visual-part-map listener
getAdaptable().visualPartMapProperty()
.removeListener(visualPartMapListener);
}
super.setAdaptable(adaptable);
if (adaptable != null) {
// register for visual-part-map changes
adaptable.visualPartMapProperty()
.addListener(visualPartMapListener);
}
// start with a clean HoverModel
clearHover();
clearHoverIntent();
}
/**
* Sets the hovered {@link IVisualPart} to the given value. The given part
* may be <code>null</code> in order to unhover.
*
* @param cp
* hovered {@link IVisualPart} or <code>null</code>
*/
public void setHover(IVisualPart<? extends Node> cp) {
if (cp != hoverProperty.get()) {
hoverProperty.set(cp);
}
}
/**
* Sets the hover intent {@link IContentPart} to the given value. The given
* part may be <code>null</code> to indicate unhovering.
*
* @param cp
* The hover intent {@link IContentPart} or <code>null</code>.
*/
public void setHoverIntent(IContentPart<? extends Node> cp) {
if (cp != hoverIntentProperty.get()) {
hoverIntentProperty.set(cp);
}
}
}