305 lines
11 KiB
Java
305 lines
11 KiB
Java
package ch.psi.mxsc;
|
|
|
|
import ch.psi.mxsc.Puck.PuckType;
|
|
import ch.psi.pshell.imaging.DimensionDouble;
|
|
import ch.psi.pshell.imaging.PointDouble;
|
|
import ch.psi.utils.swing.MainFrame;
|
|
import ch.psi.utils.swing.SwingUtils;
|
|
import java.awt.BasicStroke;
|
|
import java.awt.Color;
|
|
import java.awt.Dimension;
|
|
import java.awt.Font;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.Point;
|
|
import java.awt.Rectangle;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
/**
|
|
*
|
|
*/
|
|
public class PuckGraphics {
|
|
final static PointDouble labelPositionWithImage = new PointDouble(0.0, 36.0);
|
|
Puck puck;
|
|
final BasePlate basePlate ;
|
|
final boolean rotated;
|
|
final BasePlateGraphics basePlateGraphics;
|
|
List<SampleGraphics> sampleGraphics = new ArrayList<>();
|
|
|
|
|
|
public PuckGraphics(Puck puck, BasePlateGraphics basePlateGraphics){
|
|
this.puck = puck;
|
|
basePlate = puck.getBasePlate();
|
|
this.basePlateGraphics = basePlateGraphics;
|
|
this.rotated = (basePlateGraphics!=null);
|
|
for (Sample sample : puck.getSamples()){
|
|
sampleGraphics.add(new SampleGraphics(sample, this));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public PointDouble getRotatedPosition(PointDouble ref) {
|
|
double rotation = - puck.angle * Math.PI / 180.0;
|
|
double x = ref.x * Math.cos(rotation) - ref.y * Math.sin(rotation);
|
|
double y = ref.y * Math.cos(rotation) + ref.x * Math.sin(rotation);
|
|
return new PointDouble(x,y );
|
|
}
|
|
|
|
public PointDouble getSamplePosition(Sample sample) {
|
|
//PointDouble ref = samplesPosition[sample.index];
|
|
//return getRotatedPosition(ref);
|
|
return puck.samplesPosition[sample.index];
|
|
}
|
|
|
|
public Point getDrawUnipuckLedPosition(){
|
|
PointDouble ref = puck.ledUnipuckPosition;
|
|
return getDrawPosition(ref);
|
|
}
|
|
|
|
public Point getDrawMinispineLedPosition(){
|
|
PointDouble ref = puck.ledMinispinePosition;
|
|
return getDrawPosition(ref);
|
|
}
|
|
|
|
|
|
int getUnipuckLedSize() {
|
|
return getDrawSize(puck.unipuckLedSize) ;
|
|
}
|
|
|
|
int getMinispineLedSize() {
|
|
return getDrawSize(puck.minispineLedSize) ;
|
|
}
|
|
|
|
int getDrawSize(double refSize) {
|
|
return (int) ((refSize / puck.getSize().getWidth()) * getDrawSize()) ;
|
|
}
|
|
|
|
Point getDrawPosition(PointDouble refPosition) {
|
|
Point puckCenter = getDrawPosition();
|
|
int puckDrawSize = getDrawSize();
|
|
DimensionDouble puckSize = puck.getSize();
|
|
PointDouble pos = rotated ? getRotatedPosition(refPosition) : refPosition;
|
|
return new Point( (int) ((pos.x / puckSize.getWidth())* puckDrawSize/2 + puckCenter.x) ,
|
|
(int) ((pos.y / puckSize.getHeight())* puckDrawSize/2 + puckCenter.y) );
|
|
}
|
|
|
|
public boolean isHighlithted() {
|
|
return puck.isSelected() || puck.isSegmentSelected();
|
|
}
|
|
|
|
Color getEmptyColor(){
|
|
return isHighlithted() ? new Color(212, 212, 212) : Color.LIGHT_GRAY;
|
|
}
|
|
|
|
Color getErrorColor(){
|
|
if (puck.getDisplayDetectionError()){
|
|
return isHighlithted() ? new Color(192, 10, 10) : new Color(192, 128, 128);
|
|
}
|
|
return getEmptyColor();
|
|
}
|
|
|
|
Color getColor() {
|
|
Color ret = Color.LIGHT_GRAY;
|
|
if (puck.isDisabled()){
|
|
return basePlateGraphics.getColor();
|
|
}
|
|
switch (puck.detection) {
|
|
case Empty:
|
|
//ret = isHighlithted() ? new Color(224, 224, 224) : Color.LIGHT_GRAY;
|
|
ret = getEmptyColor();
|
|
break;
|
|
case Present:
|
|
if ((puck.puckType != null) && (puck.puckType != PuckType.Unknown)){
|
|
switch (puck.puckType){
|
|
case Minispine:
|
|
ret = isHighlithted() ? new Color(0, 200, 80) : new Color(128, 232, 152);
|
|
break;
|
|
case Unipuck:
|
|
ret = isHighlithted() ? new Color(0, 140, 140) : new Color(128, 192, 192);
|
|
break;
|
|
case Empty:
|
|
case Error:
|
|
ret = getErrorColor();
|
|
break;
|
|
}
|
|
} else {
|
|
ret = isHighlithted() ? new Color(0, 140, 140) : new Color(128, 192, 192);
|
|
}
|
|
break;
|
|
case Error:
|
|
ret = getErrorColor();
|
|
break;
|
|
case Offline:
|
|
ret = isHighlithted() ? new Color(250, 255, 48) : new Color(253, 194, 41);
|
|
//ret = isHighlithted() ? new Color(230, 142, 40) : new Color(216, 159, 93);
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int getDrawSize() {
|
|
//All pucks
|
|
if (basePlateGraphics!=null) {
|
|
Rectangle rect = basePlateGraphics.getBoundingBox(); //TODO
|
|
int ret = Math.min((int) Math.round(((double)puck.getSize().getWidth() / basePlate.getSize().getWidth()) * rect.width),
|
|
(int) Math.round(((double)puck.getSize().getHeight() / basePlate.getSize().getHeight()) * rect.height)
|
|
);
|
|
if (puck.isSelected()) {
|
|
ret += 2;
|
|
}
|
|
return ret;
|
|
} else {
|
|
//Single puck plot
|
|
assertPlottingBoundariesDefined() ;
|
|
return Math.min(plotRect.width, plotRect.height);
|
|
}
|
|
}
|
|
|
|
void assertPlottingBoundariesDefined(){
|
|
if ((basePlateGraphics==null) && (plotRect==null)){
|
|
throw new RuntimeException ("No plotting boundaries defined");
|
|
}
|
|
}
|
|
|
|
Point getDrawPosition() {
|
|
//All pucks
|
|
if (basePlateGraphics!=null) {
|
|
Rectangle rect = basePlateGraphics.getBoundingBox();
|
|
DimensionDouble plateSize = basePlate.getSize();
|
|
PointDouble pos = basePlate.getPuckPosition(puck);
|
|
return new Point( (int) Math.round(((double)pos.x / plateSize.getWidth()) * rect.width + rect.getCenterX()),
|
|
(int) Math.round(((double)pos.y / plateSize.getHeight()) * rect.height + rect.getCenterY())
|
|
);
|
|
} else {
|
|
//Single puck plot
|
|
assertPlottingBoundariesDefined() ;
|
|
return new Point((int) plotRect.getCenterX(), (int) plotRect.getCenterY());
|
|
}
|
|
}
|
|
|
|
Color getLabelColor(boolean drawBackground) {
|
|
if (puck.isDisabled()){
|
|
return Color.RED;
|
|
}
|
|
return drawBackground ? (isHighlithted() ? Color.BLACK : new Color(92, 92, 92)) : (isHighlithted() ? new Color(0, 255, 0) : new Color(0, 162, 0));
|
|
|
|
}
|
|
|
|
Font getLabelFont() {
|
|
if (basePlateGraphics!=null) {
|
|
return new Font("Segoe UI", Font.BOLD, 12);
|
|
}
|
|
return new Font("Segoe UI", Font.BOLD, 14);
|
|
}
|
|
|
|
Font getIdFont() {
|
|
if (basePlateGraphics!=null) {
|
|
return new Font("Segoe UI", Font.PLAIN, 9);
|
|
}
|
|
return new Font("Segoe UI", Font.PLAIN, 9);
|
|
}
|
|
|
|
Point getLabelDrawPosition(String text, Graphics g, boolean drawBackground, boolean hasId) {
|
|
Point pos = drawBackground ? getDrawPosition() : getDrawPosition(labelPositionWithImage);
|
|
Dimension textSize = SwingUtils.getTextSize(text, g.getFontMetrics());
|
|
return new Point(pos.x - textSize.width / 2 , pos.y + (g.getFontMetrics().getAscent() / 2) - (hasId ? 5: 0));
|
|
}
|
|
|
|
Color getBorderColor(boolean drawBackground) {
|
|
if (drawBackground) {
|
|
if (puck.isDisabled()){
|
|
return Color.RED;
|
|
}
|
|
/*if (!isEnabled()){
|
|
return Color.GRAY;
|
|
} else */
|
|
if (isHighlithted()) {
|
|
return new Color(0, 0, 0);
|
|
}
|
|
return Color.GRAY;
|
|
}
|
|
return isHighlithted() ? new Color(0, 208, 0) : new Color(0, 128, 0);
|
|
}
|
|
|
|
int getBorderWidth(boolean drawBackground) {
|
|
return drawBackground ? puck.isSegmentSelected() ? 2 : 1 : puck.isSegmentSelected() ? 2 : 1;
|
|
}
|
|
|
|
int getReferenceDrawSize() {
|
|
return getDrawSize(puck.referenceSize) ;
|
|
}
|
|
|
|
Point getReferenceDrawPosition() {
|
|
return getDrawPosition(new PointDouble(0, -67.0));
|
|
|
|
}
|
|
|
|
Rectangle plotRect;
|
|
|
|
void draw(Graphics2D g, Rectangle plotRect, boolean drawSamples, boolean drawId, boolean drawBackground) {
|
|
this.plotRect = plotRect;
|
|
if (puck.isDisabled()){
|
|
drawSamples=false;
|
|
}
|
|
Point position = getDrawPosition();
|
|
int size = getDrawSize();
|
|
if (drawBackground) {
|
|
g.setColor(getColor());
|
|
g.fillOval(position.x - size / 2, position.y - size / 2, size, size);
|
|
}
|
|
g.setColor(getBorderColor(drawBackground));
|
|
g.setStroke(new BasicStroke(getBorderWidth(drawBackground)));
|
|
g.drawOval(position.x - size / 2, position.y - size / 2, size, size);
|
|
g.setStroke(new BasicStroke(1f));
|
|
if (drawSamples) {
|
|
//Draw samples
|
|
for (SampleGraphics sg : sampleGraphics) {
|
|
sg.draw(g, drawBackground);
|
|
}
|
|
}
|
|
|
|
//Draw reference
|
|
Color refColor = MainFrame.isDark() ? Color.DARK_GRAY : new Color(214, 217, 223);
|
|
if ((basePlateGraphics != null) && basePlateGraphics.drawContour) {
|
|
refColor = basePlateGraphics.getColor();
|
|
}
|
|
|
|
if (drawBackground){
|
|
g.setColor(refColor);
|
|
position = getReferenceDrawPosition();
|
|
size = getReferenceDrawSize();
|
|
//size+=1;
|
|
g.fillOval(position.x - size / 2, position.y - size / 2, size, size);
|
|
g.setColor(getBorderColor(drawBackground));
|
|
//size-=1;
|
|
g.setStroke(new BasicStroke(getBorderWidth(drawBackground)));
|
|
g.drawArc(position.x - size / 2, position.y - size / 2 , size, size, (int) (190 + (rotated ? puck.angle : 0)), 154);
|
|
g.setStroke(new BasicStroke(1f));
|
|
} else {
|
|
Point pu = getDrawUnipuckLedPosition();
|
|
Point pm = getDrawMinispineLedPosition();
|
|
int unipuckSize = getUnipuckLedSize();
|
|
int minispineSize = getMinispineLedSize();
|
|
g.setColor(getBorderColor(drawBackground));
|
|
g.drawOval(pu.x - unipuckSize / 2, pu.y - unipuckSize / 2, unipuckSize, unipuckSize);
|
|
g.drawOval(pm.x - minispineSize / 2, pm.y - minispineSize / 2, minispineSize, minispineSize);
|
|
}
|
|
|
|
//Draw text
|
|
String id = puck.getId();
|
|
boolean hasId = drawId && (id!= null);
|
|
String text = puck.getName(); //String.valueOf(getIndex() + 1);
|
|
g.setColor(getLabelColor(drawBackground));
|
|
g.setFont(getLabelFont());
|
|
Point labelPosition = getLabelDrawPosition(text, g, drawBackground, hasId);
|
|
g.drawString(text, labelPosition.x, labelPosition.y);
|
|
if (hasId) {
|
|
g.setFont(getIdFont());
|
|
Dimension textSize = SwingUtils.getTextSize(id, g.getFontMetrics());
|
|
g.drawString(id, getDrawPosition().x - textSize.width/2 , getDrawPosition().y + 14);
|
|
}
|
|
}
|
|
}
|