package net.sourceforge.fidocadj.circuit;
import javax.swing.*;
import java.awt.*;
import net.sourceforge.fidocadj.geom.*;
import net.sourceforge.fidocadj.globals.*;
/** Draw a ruler.
<pre>
This file is part of FidoCadJ.
FidoCadJ is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FidoCadJ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FidoCadJ. If not,
@see <a href=http://www.gnu.org/licenses/>http://www.gnu.org/licenses/</a>.
Copyright 2015 by Davide Bucci
</pre>
@author Davide Bucci
*/
public class Ruler
{
// Font to be used to draw the ruler.
private static final String rulerFont = "Lucida Sans Regular";
// Color of elements during editing.
private final Color rulerColor;
private final Color textColor;
// Begin and end coordinates.
private int rulerStartX;
private int rulerStartY;
private int rulerEndX;
private int rulerEndY;
// Is the ruler active?
private boolean isActiveRuler;
/** Constructor, specify the colors to be employed.
@param rc the color of ruler elements.
@param tc the color of text elements.
*/
public Ruler(Color rc, Color tc)
{
rulerColor=rc;
textColor=tc;
isActiveRuler=false;
}
/** Set wether the ruler should be drawn or not.
@param s true if the ruler should be drawn.
*/
public void setActive(boolean s)
{
isActiveRuler=s;
}
/** Gets the current status of the ruler.
@return true if the ruler should be drawn, false if not.
*/
public boolean isActive()
{
return isActiveRuler;
}
/** Draws a ruler to ease measuring distances.
@param g the graphic context.
@param cs the coordinate mapping.
*/
public void drawRuler(Graphics g, MapCoordinates cs)
{
if (!isActiveRuler)
return;
int sx=rulerStartX;
int sy=rulerStartY;
int ex=rulerEndX;
int ey=rulerEndY;
double length;
//MapCoordinates cs=dmp.getMapCoordinates();
int xa = cs.unmapXnosnap(sx);
int ya = cs.unmapYnosnap(sy);
int xb = cs.unmapXnosnap(ex);
int yb = cs.unmapYnosnap(ey);
int x1, y1, x2, y2;
double x, y;
// Calculates the ruler length.
length = Math.sqrt((double)(xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));
g.drawLine(sx, sy, ex, ey);
// A little bit of trigonometry :-)
double alpha;
if (sx==ex)
alpha = Math.PI/2.0+(ey-sy<0?0:Math.PI);
else
alpha = Math.atan((double)(ey-sy)/(double)(ex-sx));
alpha += ex-sx>0?0:Math.PI;
// Those magic numers are the lenghts of the tics (major and minor)
double l = 5.0;
if (cs.getXMagnitude()<1.0) {
l=10;
} else if(cs.getXMagnitude() > 5.0) {
l=1;
} else {
l=5;
}
double ll=0.0;
double ld=5.0;
int m = 5;
int j=0;
double dex = sx + length*Math.cos(alpha)*cs.getXMagnitude();
double dey = sy + length*Math.sin(alpha)*cs.getYMagnitude();
alpha += Math.PI/2.0;
boolean debut=true;
// Draw the ticks.
for(double i=0; i<=length; i+=l) {
if (j++==m || debut) {
j=1;
ll=2*ld;
debut=false;
} else {
ll=ld;
}
x = (dex*i)/length+((double)sx*(length-i))/length;
y = (dey*i)/length+((double)sy*(length-i))/length;
x1 = (int)(x - ll*Math.cos(alpha));
x2 = (int)(x + ll*Math.cos(alpha));
y1 = (int)(y - ll*Math.sin(alpha));
y2 = (int)(y + ll*Math.sin(alpha));
g.drawLine(x1, y1, x2, y2);
}
Font f=new Font(rulerFont,Font.PLAIN,10);
g.setFont(f);
String t1 = Globals.roundTo(length,2);
// Remember that one FidoCadJ logical unit is 127 microns.
String t2 = Globals.roundTo(length*.127,2)+" mm";
FontMetrics fm = g.getFontMetrics(f);
// Draw the box at the end, with the measurement results.
g.setColor(Color.white);
g.fillRect(ex+10, ey, Math.max(fm.stringWidth(t1),
fm.stringWidth(t2))+1, 24);
g.setColor(rulerColor);
g.drawRect(ex+9, ey-1, Math.max(fm.stringWidth(t1),
fm.stringWidth(t2))+2, 25);
g.setColor(textColor);
g.drawString(t1, ex+10, ey+10);
g.drawString(t2, ex+10, ey+20);
}
/** Define the coordinates of the starting point of the ruler.
@param sx the x coordinate.
@param sy the y coordinate.
*/
public void setRulerStart(int sx, int sy)
{
rulerStartX=sx;
rulerStartY=sy;
}
/** Define the coordinates of the ending point of the ruler.
@param sx the x coordinate.
@param sy the y coordinate.
*/
public void setRulerEnd(int sx, int sy)
{
rulerEndX=sx;
rulerEndY=sy;
}
/** Get the x coordinate of the starting point of the ruler.
@return the x coordinate.
*/
public int getRulerStartX()
{
return rulerStartX;
}
/** Get the y coordinate of the starting point of the ruler.
@return the y coordinate.
*/
public int getRulerStartY()
{
return rulerStartY;
}
}