blob: ae5cabb602b497d1fff9f54d45473770f4a75922 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 University of Illinois at Urbana-Champaign 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:
* Abhishek Sharma, UIUC - Initial API and implementation
*******************************************************************************/
package org.eclipse.rephraserengine.internal.ui.browser;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
/**
* An edge in the {@link EdgesTab}.
*
* @author Abhishek Sharma
*/
class EdgeArrow
{
public static final int arrowAngle = 30;
public static final int arrowLength = 15;
private Point source;
private Point target;
private Point midpoint;
private Double angle;
public EdgeArrow(Rectangle srcRect, Rectangle sinkRect)
{
setTargetAndSourcePoint(srcRect, sinkRect);
setMidpoint();
setAngleBetweenLineAndXAxis();
}
private void setTargetAndSourcePoint(Rectangle srcRect, Rectangle sinkRect)
{
if (srcRect.y < sinkRect.y)
{
target = new Point(sinkRect.x, sinkRect.y);
source = new Point(srcRect.x, srcRect.y + srcRect.height);
}
else if (srcRect.y > sinkRect.y)
{
target = new Point(sinkRect.x, sinkRect.y + sinkRect.height);
source = new Point(srcRect.x, srcRect.y);
}
else
{
target = new Point(sinkRect.x, (sinkRect.height) / 2 + sinkRect.y);
source = new Point(srcRect.x, (srcRect.height) / 2 + srcRect.y);
}
}
private void setMidpoint()
{
midpoint = new Point((source.x + target.x) / 2, (target.y + source.y) / 2);
}
private void setAngleBetweenLineAndXAxis()
{
// atan2 -returns the angle between the line drawn between the source and sink rectangles
// and the positive x-axis
angle = Math.atan2((target.y - source.y), (target.x - source.x));
}
public void drawOn(GC gc)
{
drawLine(gc);
drawArrow(gc);
}
private void drawLine(GC gc)
{
gc.drawLine(source.x, source.y, target.x, target.y);
}
private void drawArrow(GC gc)
{
int degreesBetweenArrowsAndLine = getDegrees(angle) + arrowAngle + 180;
double radiansBetweenArrowsAndLine = getRadians(degreesBetweenArrowsAndLine);
Point arrowPoint1 = new Point(midpoint.x
+ (int)(arrowLength * Math.cos(radiansBetweenArrowsAndLine)), midpoint.y
+ (int)(arrowLength * Math.sin(radiansBetweenArrowsAndLine)));
// refers to the degrees between the second arrowpoint and the line between source and sink
degreesBetweenArrowsAndLine = getDegrees(angle) - arrowAngle + 180;
radiansBetweenArrowsAndLine = getRadians(degreesBetweenArrowsAndLine);
// sets the x and y coordinates of arrowpoint1 in the direction obtained from the degrees
// calculated
// relative to the line drawn between source and sink rectangle
Point arrowPoint2 = new Point(midpoint.x
+ (int)(arrowLength * Math.cos(radiansBetweenArrowsAndLine)), midpoint.y
+ (int)(arrowLength * Math.sin(radiansBetweenArrowsAndLine)));
gc.setLineWidth(gc.getLineWidth() + 2);
gc.drawLine(midpoint.x, midpoint.y, arrowPoint1.x, arrowPoint1.y);
gc.drawLine(midpoint.x, midpoint.y, arrowPoint2.x, arrowPoint2.y);
gc.setLineWidth(gc.getLineWidth() - 2);
}
private double getRadians(double d)
{
return (d) * Math.PI / 180;
}
private int getDegrees(Double radians)
{
double degrees = (180 / Math.PI) * radians;
return (int)(degrees);
}
}