/******************************************************************************
* Copyright (c) 2016 Oracle
* 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:
* Shenxue Zhou - initial implementation and ongoing maintenance
******************************************************************************/
package org.eclipse.sapphire.ui.swt.gef.figures;
import org.eclipse.draw2d.AbstractBorder;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.sapphire.ui.LineStyle;
import org.eclipse.sapphire.ui.diagram.shape.def.BorderComponent;
import org.eclipse.sapphire.ui.swt.gef.model.DiagramResourceCache;
import org.eclipse.sapphire.ui.swt.gef.presentation.RectanglePresentation;
/**
* @author <a href="mailto:shenxue.zhou@oracle.com">Shenxue Zhou</a>
*/
public class RectangleBorder extends AbstractBorder
{
private RectanglePresentation rectPresentation;
private DiagramResourceCache resourceCache;
private boolean hasUniformBorders;
public RectangleBorder(RectanglePresentation rectPresentation, DiagramResourceCache resourceCache)
{
this.rectPresentation = rectPresentation;
this.resourceCache = resourceCache;
this.hasUniformBorders = hasUniformBorders();
}
public Insets getInsets(IFigure figure)
{
int tw, bw, lw, rw;
tw = this.rectPresentation.getTopBorder().getWeight().content();
bw = this.rectPresentation.getBottomBorder().getWeight().content();
lw = this.rectPresentation.getLeftBorder().getWeight().content();
rw = this.rectPresentation.getRightBorder().getWeight().content();
return new Insets(tw, lw, bw, rw);
}
public void paint( final IFigure figure, final Graphics graphics, final Insets insets )
{
Rectangle rectangle = new Rectangle();
rectangle.setBounds(getPaintRectangle(figure, insets));
BorderComponent borderDef = this.rectPresentation.getTopBorder();
if (this.hasUniformBorders && borderDef.getWeight().content() > 0)
{
int w = borderDef.getWeight().content();
rectangle = FigureUtil.getAdjustedRectangle(rectangle, 1.0, w);
int cornerRadius = this.rectPresentation.getCornerRadius();
float cornerWidth = cornerRadius;
float cornerHeight = cornerRadius;
// adjust corner for the inner path (formula found by experimenting)
if (cornerRadius > 0) {
cornerHeight = Math.max(1, cornerHeight - (w + cornerHeight / 64));
cornerWidth = Math.max(1, cornerWidth - (w + cornerWidth / 64));
}
graphics.setLineWidth(borderDef.getWeight().content());
graphics.setForegroundColor(resourceCache.getColor(borderDef.getColor().content()));
graphics.setLineStyle(FigureUtil.convertLineStyle(borderDef.getStyle().content()));
graphics.drawRoundRectangle(rectangle,
Math.max(0, (int)cornerWidth),
Math.max(0, (int)cornerHeight));
}
else
{
if( borderDef.getWeight().content() > 0 )
{
int w = borderDef.getWeight().content();
graphics.setLineWidth(w);
graphics.setForegroundColor(resourceCache.getColor(borderDef.getColor().content()));
graphics.setLineStyle(FigureUtil.convertLineStyle(borderDef.getStyle().content()));
int inset = Math.max(1, w >> 1);
int x = rectangle.x;
int y = rectangle.y + inset;
int x2 = rectangle.x + rectangle.width;
graphics.drawLine(x, y, x2, y);
}
borderDef = this.rectPresentation.getBottomBorder();
if( borderDef.getWeight().content() > 0 )
{
int w = borderDef.getWeight().content();
graphics.setLineWidth(w);
graphics.setForegroundColor(resourceCache.getColor(borderDef.getColor().content()));
graphics.setLineStyle(FigureUtil.convertLineStyle(borderDef.getStyle().content()));
int inset = Math.max(1, w >> 1);
int x = rectangle.x;
int y = rectangle.y + rectangle.height - inset;
int x2 = rectangle.x + rectangle.width;
graphics.drawLine(x, y, x2, y);
}
borderDef = this.rectPresentation.getLeftBorder();
if( borderDef.getWeight().content() > 0 )
{
int w = borderDef.getWeight().content();
graphics.setLineWidth(w);
graphics.setForegroundColor(resourceCache.getColor(borderDef.getColor().content()));
graphics.setLineStyle(FigureUtil.convertLineStyle(borderDef.getStyle().content()));
int inset = Math.max(1, w >> 1);
int x = rectangle.x + inset;
int y = rectangle.y;
int y2 = rectangle.y + rectangle.height;
graphics.drawLine(x, y, x, y2);
}
borderDef = this.rectPresentation.getRightBorder();
if( borderDef.getWeight().content() > 0 )
{
int w = borderDef.getWeight().content();
graphics.setLineWidth(w);
graphics.setForegroundColor(resourceCache.getColor(borderDef.getColor().content()));
graphics.setLineStyle(FigureUtil.convertLineStyle(borderDef.getStyle().content()));
int inset = Math.max(1, w >> 1);
int x = rectangle.x + rectangle.width - inset;
int y = rectangle.y;
int y2 = rectangle.y + rectangle.height;
graphics.drawLine(x, y, x, y2);
}
}
}
private boolean hasUniformBorders()
{
org.eclipse.sapphire.Color tc, bc, lc, rc;
tc = this.rectPresentation.getTopBorder().getColor().content();
bc = this.rectPresentation.getBottomBorder().getColor().content();
lc = this.rectPresentation.getLeftBorder().getColor().content();
rc = this.rectPresentation.getRightBorder().getColor().content();
if (!(tc.equals(bc) && tc.equals(lc) && tc.equals(rc)))
{
return false;
}
int tw, bw, lw, rw;
tw = this.rectPresentation.getTopBorder().getWeight().content();
bw = this.rectPresentation.getBottomBorder().getWeight().content();
lw = this.rectPresentation.getLeftBorder().getWeight().content();
rw = this.rectPresentation.getRightBorder().getWeight().content();
if (!(tw == bw && tw == lw && tw == rw))
{
return false;
}
LineStyle ts, bs, ls, rs;
ts = this.rectPresentation.getTopBorder().getStyle().content();
bs = this.rectPresentation.getBottomBorder().getStyle().content();
ls = this.rectPresentation.getLeftBorder().getStyle().content();
rs = this.rectPresentation.getRightBorder().getStyle().content();
if (!(ts == bs && ts == ls && ts == rs))
{
return false;
}
return true;
}
}