/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.internal.mindmap;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.swt.graphics.Image;
import org.xmind.core.Core;
import org.xmind.core.ITopic;
import org.xmind.core.event.CoreEvent;
import org.xmind.core.event.ICoreEventRegister;
import org.xmind.core.marker.IMarker;
import org.xmind.core.marker.IMarkerRef;
import org.xmind.gef.GEF;
import org.xmind.gef.draw2d.SizeableImageFigure;
import org.xmind.gef.draw2d.graphics.GraphicsUtils;
import org.xmind.gef.graphicalpolicy.IStyleSelector;
import org.xmind.gef.part.IPart;
import org.xmind.gef.part.IRequestHandler;
import org.xmind.gef.policy.NullEditPolicy;
import org.xmind.gef.service.IFeedback;
import org.xmind.ui.internal.svgsupport.SVGImageData;
import org.xmind.ui.internal.svgsupport.SVGImageFigure;
import org.xmind.ui.internal.svgsupport.SVGReference;
import org.xmind.ui.mindmap.IMarkerPart;
import org.xmind.ui.mindmap.ISelectionFeedbackHelper;
import org.xmind.ui.mindmap.ITopicPart;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.resources.ImageReference;
import org.xmind.ui.style.StyleUtils;
import org.xmind.ui.style.TextStyleData;
import org.xmind.ui.util.MarkerImageDescriptor;
public class MarkerPart extends MindMapPartBase implements IMarkerPart {
private ImageReference imageRef = null;
private SVGReference svgRef = null;
private Dimension preferredSize = null;
private LocalResourceManager resourceManager;
public MarkerPart() {
setDecorator(MarkerDecorator.getInstance());
}
@SuppressWarnings("unchecked")
@Override
public Object getAdapter(Class adapter) {
if (adapter.isAssignableFrom(IMarkerRef.class))
return getMarkerRef();
if (adapter.isAssignableFrom(IMarker.class))
return getMarker();
if (adapter.isAssignableFrom(ITopic.class))
return getTopic();
if (adapter == Image.class)
return getImage();
if (adapter == SVGImageData.class)
return getSVGData();
return super.getAdapter(adapter);
}
protected IFigure createFigure() {
if (svgRef != null) {
SVGImageFigure figure = new SVGImageFigure();
figure.setManager(resourceManager);
return figure;
} else
return new SizeableImageFigure();
}
public IMarkerRef getMarkerRef() {
return (IMarkerRef) super.getRealModel();
}
protected void register() {
registerModel(getMarkerRef());
super.register();
}
protected void unregister() {
super.unregister();
unregisterModel(getMarkerRef());
}
public IMarker getMarker() {
IMarkerRef markerRef = getMarkerRef();
return markerRef == null ? null : markerRef.getMarker();
}
public ITopic getTopic() {
return getMarkerRef().getParent();
}
public ITopicPart getTopicPart() {
if (getParent() instanceof ITopicPart)
return (ITopicPart) getParent();
return null;
}
public void setParent(IPart parent) {
if (getParent() instanceof TopicPart) {
((TopicPart) getParent()).removeMarker(this);
}
super.setParent(parent);
updateMarker();
if (getParent() instanceof TopicPart) {
((TopicPart) getParent()).addMarker(this);
}
}
public Image getImage() {
if (imageRef != null && !imageRef.isDisposed())
return imageRef.getImage();
return null;
}
public SVGImageData getSVGData() {
if (svgRef != null)
return svgRef.getSVGData();
return null;
}
@Override
protected void onActivated() {
this.resourceManager = new LocalResourceManager(
JFaceResources.getResources());
super.onActivated();
}
protected void onDeactivated() {
if (imageRef != null) {
imageRef.dispose();
imageRef = null;
}
if (svgRef != null) {
svgRef = null;
this.resourceManager.dispose();
}
super.onDeactivated();
}
@Override
public void setModel(Object model) {
// step 1, new marker part
// step 2, set model
super.setModel(model);
// step 3, ensure image type
IMarkerRef markerRef = (IMarkerRef) ((ViewerModel) model)
.getRealModel();
IMarker marker = markerRef.getMarker();
String svgPath = marker != null ? marker.getSVGPath() : null;
if (svgPath != null && !"".equals(svgPath)) { //$NON-NLS-1$
this.svgRef = createSVGReference();
} else {
this.imageRef = createImageReference();
}
}
/*
* (non-Javadoc)
*
* @see
* org.xmind.gef.part.GraphicalEditPart#containsPoint(org.eclipse.draw2d
* .geometry.Point)
*/
@Override
public boolean containsPoint(Point position) {
return super.containsPoint(position);
}
@Override
protected void updateView() {
updateToolTip();
super.updateView();
}
public IFigure findTooltipAt(Point position) {
if (containsPoint(position)) {
IFigure toolTip = getFigure().getToolTip();
if (toolTip != null)
return toolTip;
return new Label(getMarkerRef().getDescription());
}
return null;
}
protected void declareEditPolicies(IRequestHandler reqHandler) {
super.declareEditPolicies(reqHandler);
reqHandler.installEditPolicy(GEF.ROLE_SELECTABLE,
NullEditPolicy.getInstance());
reqHandler.installEditPolicy(GEF.ROLE_DELETABLE,
MindMapUI.POLICY_DELETABLE);
reqHandler.installEditPolicy(GEF.ROLE_MOVABLE,
MindMapUI.POLICY_MARKER_MOVABLE);
}
protected IFeedback createFeedback() {
return new SimpleSelectionFeedback(this);
}
protected ISelectionFeedbackHelper createSelectionFeedbackHelper() {
return new SelectionFeedbackHelper();
}
@Override
protected void installModelListeners() {
super.installModelListeners();
}
protected void registerCoreEvents(Object source,
ICoreEventRegister register) {
super.registerCoreEvents(source, register);
register.register(Core.Style);
ITopic topic = getMarkerRef().getParent();
register.setNextSourceFrom(topic);
register.register(Core.Style);
}
public void handleCoreEvent(CoreEvent event) {
String type = event.getType();
if (Core.Style.equals(type)) {
updateMarker();
}
}
private void updateMarker() {
if (svgRef == null) {
if (imageRef != null) {
imageRef.dispose();
}
imageRef = createImageReference();
} else {
// svgRef don't have to create a new reference,
// but the preferredSize must be calculated again
preferredSize = calculateSVGPreferredSize();
}
update();
}
private ImageReference createImageReference() {
preferredSize = calculateImagePreferredSize();
int hintSize = preferredSize == null ? -1 : preferredSize.width;
return new ImageReference(MarkerImageDescriptor.createFromMarkerRef(
getMarkerRef(), hintSize, hintSize), false);
}
private SVGReference createSVGReference() {
preferredSize = calculateSVGPreferredSize();
String resourcePath = MarkerImageDescriptor.RESOURCE_URL_PREFIX
+ getMarker().getSVGPath();
SVGReference ref = new SVGReference(resourcePath);
if (this.resourceManager == null)
this.resourceManager = new LocalResourceManager(
JFaceResources.getResources());
return ref;
}
private Dimension calculateSVGPreferredSize() {
ITopicPart tp = getTopicPart();
if (tp == null)
return null;
IStyleSelector ss = (IStyleSelector) tp
.getAdapter(IStyleSelector.class);
TextStyleData data = StyleUtils.getTextStyleData(tp, ss, null);
int leading = GraphicsUtils.getAdvanced()
.getFontMetrics(JFaceResources.getDefaultFont()).getLeading();
return new Dimension(data.height + leading, data.height + leading);
}
private Dimension calculateImagePreferredSize() {
ITopicPart tp = getTopicPart();
if (tp == null)
return null;
IStyleSelector ss = (IStyleSelector) tp
.getAdapter(IStyleSelector.class);
TextStyleData data = StyleUtils.getTextStyleData(tp, ss, null);
int fontSize = data.height;
if (fontSize < 13) {
return new Dimension(16, 16);
} else if (fontSize >= 13 && fontSize < 25) {
return new Dimension(24, 24);
} else {
return new Dimension(32, 32);
}
}
public Dimension getPreferredSize() {
return preferredSize;
}
public ResourceManager getResourceManager() {
return resourceManager;
}
}