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 = 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); } } }