/* ******************************************************************************
* 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.MarginBorder;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.xmind.gef.GEF;
import org.xmind.gef.IGraphicalViewer;
import org.xmind.gef.IViewer;
import org.xmind.gef.draw2d.IAnchor;
import org.xmind.gef.draw2d.IAnchorListener;
import org.xmind.gef.draw2d.ITextFigure;
import org.xmind.gef.draw2d.ITitledFigure;
import org.xmind.gef.draw2d.decoration.IConnectionDecoration;
import org.xmind.gef.draw2d.decoration.ICorneredDecoration;
import org.xmind.gef.draw2d.decoration.IDecoration;
import org.xmind.gef.draw2d.decoration.ILineDecoration;
import org.xmind.gef.draw2d.decoration.IShapeDecoration;
import org.xmind.gef.draw2d.geometry.Geometry;
import org.xmind.gef.graphicalpolicy.IStyleSelector;
import org.xmind.gef.part.IGraphicalPart;
import org.xmind.ui.mindmap.IConnectionPart;
import org.xmind.ui.mindmap.INodePart;
import org.xmind.ui.mindmap.ITitleTextPart;
import org.xmind.ui.style.StyleUtils;
import org.xmind.ui.style.Styles;
public abstract class DecoratedLineFeedback extends DecoratedFeedback implements
IAnchorListener {
protected class TitledDecoratedFigure extends DecoratedFigure implements
ITitledFigure {
public ITextFigure getTitle() {
ITitleTextPart title = (ITitleTextPart) host
.getAdapter(ITitleTextPart.class);
if (title != null)
return title.getTextFigure();
return null;
}
public void setTitle(ITextFigure title) {
}
}
private IGraphicalPart host;
private IFigure realLayer;
private int lineWidthExpansion = 0;
private Color lineColor = null;
private int lineStyle = SWT.DEFAULT;
private IAnchor sourceAnchor = null;
private IAnchor targetAnchor = null;
public DecoratedLineFeedback(IGraphicalPart part) {
this.host = part;
}
public IGraphicalPart getHost() {
return host;
}
protected DecoratedFigure createDecoratedFigure() {
return new TitledDecoratedFigure();
}
public void addToLayer(IFigure layer) {
if (realLayer == null) {
IViewer viewer = host.getSite().getViewer();
if (viewer instanceof IGraphicalViewer) {
realLayer = ((IGraphicalViewer) viewer)
.getLayer(GEF.LAYER_PRESENTATION);
}
}
if (realLayer != null)
layer = realLayer;
super.addToLayer(layer);
}
public void removeFromLayer(IFigure layer) {
if (realLayer != null)
layer = realLayer;
super.removeFromLayer(layer);
}
public Color getLineColor() {
return lineColor;
}
public int getLineStyle() {
return lineStyle;
}
public int getLineWidthExpansion() {
return lineWidthExpansion;
}
public void setLineColor(Color lineColor) {
this.lineColor = lineColor;
}
public void setLineStyle(int lineStyle) {
this.lineStyle = lineStyle;
}
public void setLineWidthExpansion(int expansion) {
this.lineWidthExpansion = expansion;
}
protected void updateBounds(IFigure figure) {
IFigure client = host.getFigure();
int exp = calcExpansion();
Rectangle bounds = client.getBounds().getExpanded(exp, exp);
Insets ins = Geometry.add(new Insets(client.getInsets()), exp);
figure.setBounds(bounds);
figure.setBorder(new MarginBorder(ins));
}
protected int calcExpansion() {
return getLineWidthExpansion();
}
protected void updateDecoration(IFigure figure, IDecoration decoration) {
String decorationId = decoration.getId();
IStyleSelector ss = StyleUtils.getStyleSelector(host);
updateDecoration(figure, decoration, decorationId, ss);
if (decoration instanceof IConnectionDecoration) {
((IConnectionDecoration) decoration).reroute(figure);
}
}
protected void updateDecoration(IFigure figure, IDecoration decoration,
String decorationId, IStyleSelector ss) {
if (decoration instanceof IShapeDecoration) {
decoration.setAlpha(figure, 0xff);
((IShapeDecoration) decoration).setFillAlpha(figure, 0);
((IShapeDecoration) decoration).setFillColor(figure, null);
((IShapeDecoration) decoration).setGradient(figure, false);
((IShapeDecoration) decoration).setLineAlpha(figure,
getDecorationAlpha(figure, decoration));
} else {
decoration.setAlpha(figure, getDecorationAlpha(figure, decoration));
}
if (decoration instanceof ILineDecoration) {
Color lineColor = getLineColor();
if (lineColor == null) {
lineColor = StyleUtils.getColor(host, ss, Styles.LineColor,
decorationId, Styles.DEF_BOUNDARY_LINE_COLOR);
}
((ILineDecoration) decoration).setLineColor(figure, lineColor);
int lineStyle = getLineStyle();
if (lineStyle == SWT.DEFAULT) {
lineStyle = StyleUtils.getLineStyle(host, ss, decorationId,
SWT.LINE_DASH);
}
((ILineDecoration) decoration).setLineStyle(figure, lineStyle);
int originalLineWidth = StyleUtils.getInteger(host, ss,
Styles.LineWidth, decorationId,
Styles.DEF_BOUNDARY_LINE_WIDTH);
int lineWidth = originalLineWidth + getLineWidthExpansion() * 2;
((ILineDecoration) decoration).setLineWidth(figure, lineWidth);
}
setSourceAnchor(getSourceAnchor(host), figure, decoration);
setTargetAnchor(getTargetAnchor(host), figure, decoration);
if (decoration instanceof ICorneredDecoration) {
int corner = StyleUtils.getInteger(host, ss, Styles.ShapeCorner,
decorationId, 10);
((ICorneredDecoration) decoration).setCornerSize(figure, corner);
}
decoration.setVisible(figure, isDecorationVisible(figure, decoration));
}
protected int getDecorationAlpha(IFigure figure, IDecoration decoration) {
if (host.getStatus().isPreSelected() && !host.getStatus().isSelected()) {
return 0x60;
}
return 0xff;
}
protected boolean isDecorationVisible(IFigure figure, IDecoration decoration) {
return host.getFigure().isVisible();
}
protected void disposeOldDecoration(IFigure figure, IDecoration decoration) {
setSourceAnchor(null, figure, decoration);
setTargetAnchor(null, figure, decoration);
}
protected IAnchor getSourceAnchor(IGraphicalPart part) {
if (part instanceof IConnectionPart) {
INodePart node = ((IConnectionPart) part).getSourceNode();
if (node != null)
return node.getSourceAnchor(part);
}
return null;
}
protected IAnchor getTargetAnchor(IGraphicalPart part) {
if (part instanceof IConnectionPart) {
INodePart node = ((IConnectionPart) part).getTargetNode();
if (node != null)
return node.getTargetAnchor(part);
}
return null;
}
protected void setSourceAnchor(IAnchor anchor, IFigure figure,
IDecoration decoration) {
if (anchor != this.sourceAnchor) {
if (this.sourceAnchor != null) {
unhookAnchor(this.sourceAnchor);
}
this.sourceAnchor = anchor;
if (anchor != null) {
hookAnchor(anchor);
}
figure.revalidate();
figure.repaint();
}
if (decoration instanceof IConnectionDecoration) {
((IConnectionDecoration) decoration)
.setSourceAnchor(figure, anchor);
}
}
protected void setTargetAnchor(IAnchor anchor, IFigure figure,
IDecoration decoration) {
if (anchor != this.targetAnchor) {
if (this.targetAnchor != null) {
unhookAnchor(this.targetAnchor);
}
this.targetAnchor = anchor;
if (anchor != null) {
hookAnchor(anchor);
}
figure.revalidate();
figure.repaint();
}
if (decoration instanceof IConnectionDecoration) {
((IConnectionDecoration) decoration)
.setTargetAnchor(figure, anchor);
}
}
protected void unhookAnchor(IAnchor anchor) {
anchor.removeAnchorListener(this);
}
protected void hookAnchor(IAnchor anchor) {
anchor.addAnchorListener(this);
}
public void anchorMoved(IAnchor anchor) {
if (getFigure() != null) {
updateBounds(getFigure());
}
}
}